Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ需要40秒才能结束查询-性能_C#_Performance_Linq_Ef Code First_Edmx - Fatal编程技术网

C# LINQ需要40秒才能结束查询-性能

C# LINQ需要40秒才能结束查询-性能,c#,performance,linq,ef-code-first,edmx,C#,Performance,Linq,Ef Code First,Edmx,我正在呼叫本地网络之外的外部数据库,但是查询需要40秒才能结束 我正在用edmx打电话 String Example = "Example"; var Result = EDMXEntity.Entities .Where( x => ( x.Name.ToString().ToLower().Contains(Example.ToLower()) )) .Take(50) .ToList()

我正在呼叫本地网络之外的外部数据库,但是查询需要40秒才能结束

我正在用edmx打电话

String Example = "Example";
var Result = EDMXEntity.Entities
    .Where(
        x => 
        (
            x.Name.ToString().ToLower().Contains(Example.ToLower())
        ))
    .Take(50)
    .ToList();
当前代码感谢Szer:

var Result = EDMXEntity.Entities.Where(x => SqlFunctions.PatIndex(x.Name.ToString().ToLower(), Example.ToLower()) > 0).Take(50).ToList();
SQLServerManagementStudio在不到一秒钟的时间内完成了这项工作

很可能这是由错误的缓存查询执行计划造成的,如前所述,以及

人们发现,对SQL Server运行以下命令可以解决这个问题。(可能只需要第二个命令。)


字符串比较的最佳选择是使用用例不等式,这样就不必处理字符串转换问题。在这种情况下,名称上的.ToString并不是必须的,我想也不是(同样,我也不确定它是如何存储的,所以可能需要它)。此外,对于名称,您可以尝试使用相等或至少相等

最后,您可以尝试将其拆分为一个可查询的对象,并以这种方式运行查询。通过这种方式,您可以减少用于查询本身的资源数量

编辑

因为不希望检查整个字符串,所以可以使用IndexOf来代替,以避免使用完整的字符串

见下文:

String Example = "Example";
var EDMXEntity = new List<String>();
var Query = EDMXEntity.Entities.AsQueryable();
var Result = Query
    .Where(
        x => 
        (
            x.Name.ToString().ToLower().Contains(Example.ToLower())
        ))
    .Take(50)
    .ToList();
String-Example=“Example”;
var EDMXEntity=新列表();
var Query=EDMXEntity.Entities.AsQueryable();
var结果=查询
.在哪里(
x=>
(
x、 Name.ToString().ToLower().Contains(例如.ToLower())
))
.Take(50)
.ToList();

以上我的评论的迟交回复:

问题是您正在将所有实体从数据库加载到内存,并在计算机上进行筛选。在使用数据库引擎之前,您应该过滤查询

为此,您应该使用LINQSQL提供程序映射到直接T-SQL代码的。 在本例中,您可以将
string.Contains()
替换为
SqlFunctions.PatIndex
,这几乎是相同的(它返回
int
而不是
bool

像这样:

var result = EDMXEntity.Entities
   .Where(x => SqlFunctions.PatIndex(
      stringPattern: x.Name.ToString().ToLower(), 
      target:        Example.ToLower()) > 0)
   .Take(50)
   .ToList();

您的
IQueryable
转换为
从[Extent1]中选择前50个*,其中(CAST(CHARINDEX(LOWER(@p\u linq\u 0),LOWER(当([Extent1].[Name]为NULL时为小写),然后N''ELSE[Extent1].[Name]END]作为INT))>0
。可能where子句是您提出的关于如何提高性能的问题的原因?@Lightwalker请尝试以下方法:
var Result=EDMXEntity.Entities.where(x=>SqlFunctions.PatIndex(x.Name.ToString().ToLower(),Example.ToLower())>0)@Szer这是我的第一个猜测,但sql server management studio在不到一秒钟的时间内就做到了。@Lightwalker doneDylan,这种方法的问题是,查询需要完整的字符串,这意味着如果用户的名字是“Joh”,如果搜索“Joh”,则不会得到任何数据,这就是为什么(感谢@Szer)我使用了SqlFunctions.PatIndex(“%”+Example.ToLower()+“%”,x.Name.ToString().ToLower())>0,但由于只有在执行.ToList()时才运行查询,因此可能会更快。@Lightwalker我已使用更好的实现(不只是使用完整字符串)更新了代码。linq抛出错误。。。“LINQ to Entities无法识别方法‘Int32 IndexOf(System.String,System.StringComparison)’方法,此方法无法转换为存储表达式。”编辑代码和初始代码之间的唯一区别是.AsQueryable();
var result = EDMXEntity.Entities
   .Where(x => SqlFunctions.PatIndex(
      stringPattern: x.Name.ToString().ToLower(), 
      target:        Example.ToLower()) > 0)
   .Take(50)
   .ToList();