C#linq查询-如何使用值列表在内部表上进行查询

如何解决C#linq查询-如何使用值列表在内部表上进行查询

我正在使用C#EntityFramework linq查询。我在编写以下方案时遇到麻烦。 我有个人表和别名表,并且表之间有外键关系。如果用户以“姓氏姓氏”或“姓氏姓氏”搜索,则需要给出结果(如果它存在于persontable中),否则需要查看别名表以获取结果。在database中,全名遵循格式“ lastname firstname”或“ firstname lastname”。

Person Table: (Id,Fullname)        Alias Table:(Id PersonId Fullname)
  1. 我正在按用户使用空格拆分名称搜索,并将这些字符串存储在数组中。

  2. 我能够从“人”表中成功获取结果。我无法从别名表获取结果。

  3. 以下是我正在处理的查询:

string[] lsNames = val.Split(' ',','&');
var a = this.context.Person
   .Include(x => x.Alias)
   .Where(x => x.Alias.Any(v => 
       lsNames.All(n=>v.Name.ToLower().Contains(n.ToLower()))));

我需要返回人员表并包括别名。如何使用linq查询在别名表中搜索值列表。

以上查询使我的错误评估超时。谁能帮我解决这个问题。

解决方法

如果您的应用程序要求存储的全名是“ {first} {last}”和-或“ {last} {first}”,则问题是您想比较用户输入,这可能是任何合理的用户格式,那么我将考虑解析输入字符串,确定它是否特别有效,然后根据该字符串发出特定条件。

例如,如果数据存储为“ {first} {last}”:

if (string.IsNullOrEmpty(name))
    return null; // or handle no name search provided.

var nameParts = name.Split(new [] {' ',','&'},StringSplitOptions.RemoveEmptyEntries);

var query = Context.Person.AsQueryable();

if (nameParts.Length == 1)
    query = query.Where(x => x.Fullname.Contains(nameParts[0]));
else if (nameParts.Length == 2)
{
    var combination1 = string.Join(" ",nameParts);
    Array.Reverse(nameParts);
    var combination2 = string.Join(" ",nameParts);

    query = query.Where(x => x.Fullname == combination1 || x.Fullname == combination2 );
}
else
{ // More than 2 name components,so assume they are typing 
  // "{first} {middle} {last}" or "{last},{first} {middle}"

    var combination1 = string.Join(" ",nameParts);
    // Shift the first element (last name) to the end 
    var firstElement = nameParts[0];
    Array.Copy(nameParts,1,nameParts,nameParts.Length- 1);
    nameParts[nameParts.Length - 1] = firstElement;        
    var combination2 = string.Join(" ",nameParts);

    query = query.Where(x => x.Fullname == combination1 || x.Fullname == combination2); 

}

var people = query.ToList();

这对如何搜索输入字符串施加了限制。假定根据SQL Server / w大多数默认关联,通过EF进行的数据库比较将不区分大小写。如果数据库比较是区分大小写的,那么希望数据总是以一致的大小写存储(总是大写或总是小写),那么可以在上面应用适当的大小写。理想情况下,仅输入表达式中的字符串,而不是评估字符串和实体/ db列。 (数据库需要做更多的工作)

以上情况限制了以下检查:如果用户键入单个单词(例如“ Peter”),它将找到“ Peter Smith”或“ Mitch Peterson”。如果他们键入“ Peter Smith”或“ Smith,Peter”,例如会匹配“彼得·史密斯”而不是“彼得·史密斯”。在组合之间进行较宽松的比较将导致SQL最终需要处理的工作量更多。引入用于输入的规则/期望并对其进行验证将产生更多的代码,但查询更简单/更快。类似于Contains的查询的风险在于,这使用户有可能使用诸如“我是邪恶的b或c或d或e”之类的字符串来限制查询,想像一下{{1 }}与Contains /'All`相结合,将在该结果数组中产生组合。通常,与用户输入相比更为悲观,并且让用户优化其输入内容比尝试适应接近匹配更为安全,尤其是在不处理诸如.FirstName和.LastName之类的特定列的情况下。

,

您必须使用可以建立以下谓词的帮助程序:

Expression<Func<Alias,boo>> aliasPredicate = a => 
   a.Name.ToLower().Contains(lsNames[0]) ||
   a.Name.ToLower().Contains(lsNames[1]) ...
);

例如使用LINQKit

string[] lsNames = val.ToLower().Split(' ','&');

var builder = PredicateBuilder.New<Alias>();
foreach (var n in lsNames)
{
   var name = n; // avoid closure capturing of n variable
   builder = builder.Or(a => a.Name.ToLower().Contains(name));
}

var personQuery = this.context.Person
  .Where(x => x.Alias.AsQueryable().Any(builder));

注意,它将仅检索人员,而不检索其别名。 Include(x => x.Alias)可能会降低查询速度。为了获得更好的性能,我们必须使用客户端后期处理来创建更复杂的解决方案。

使用标准IQueryable扩展名和EF Core时,建议的解决方案几乎是最好的。注意,还有一些数据库特定功能,例如全文搜索,可以显着改善查询。

,

如果遇到超时错误,则需要检查索引以确保Name被索引并且索引被正确使用。例如,如果将列设置为varchar而不是nvarchar,则SQL将在where子句中进行类型强制转换,结果可能会忽略索引。您可以在必要时强制EF不要使用unicode,但是语法会根据所使用的EF版本和配置映射的方式而有所不同。

此外,就像@Steve Py提到的那样,您不需要对字符串执行ToLower,因为大多数SQL查询都不区分大小写。

,

如果将名称拆分为多个部分并想在这些部分上搜索匹配项,那么您正在加入集合,而当我加入集合时却无法使用导航属性,我通常会选择查询语法:>

var query = from person in this.context.Person
from name in lsNames
where person.Name.StartsWith(name) || person.Aliases.Any(a => a.Name.StartsWith(name))
select person;

return query.ToList()

这可能不是最有效的搜索,因为它使用通配符,并且您可能需要完全匹配。

如果这样做,则可以使用StevePy的技术填充lsNames数组并使用类似的查询:

string[] lsNames = {combination1,combination2)

var query = from person in this.context.Person
from name in lsNames
where person.Name == name || person.Aliases.Any(a => a.Name == name)
select person;

return query.ToList()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res