【问题标题】:LINQ query performance issueLINQ 查询性能问题
【发布时间】:2013-11-05 22:33:52
【问题描述】:

我在方法语法中有以下 LINQ 表达式

IEnumerable<PageElement> elements_test = ObjectContext.PageElements
            .Where(_dateDebutCheck).Where(_dateFinCheck)
            .Where(pe => _activeLanguageCheck(pe, language))
            .Where(pe => _typeCheck(pe, typeElement))
IList<PageElement> list = elements_test.ToList();

private readonly Func<PageElement, bool> _dateDebutCheck = pe => pe.DateDebut.HasValue && pe.DateDebut.Value <= DateTime.Now;
private readonly Func<PageElement, bool> _dateFinCheck = pe => !pe.DateFin.HasValue || pe.DateFin.Value > DateTime.Now;
private readonly Func<PageElement, byte, bool> _activeLanguageCheck = (pe, l) => pe.PageElementLanguages.Where(y => y.Active).Select(y => y.LanguageId).Contains(l);
private readonly Func<PageElement, byte?, bool> _typeCheck = (pe, t) => pe.TypeId == t;

我发现当对 ToList 的调用需要相当长的时间时,我想知道是否有什么我做错了导致性能下降。我此时仅运行 ToList 作为测试,但仅返回大约 7000 条记录需要几秒钟。我该如何改进?

【问题讨论】:

  • 您知道使用Func&lt;T, bool&gt; 会自动使用LINQ To Objects 扩展而不是LINQ To SQL? EF 使用Expression&lt;Func&lt;T, bool&gt;&gt;,这意味着您正在有效地执行所有过滤客户端...
  • 我会运行 SQL Profiler 并查看正在生成什么 SQL,它应该相对易于阅读,然后从那里获取。如果它没有像 Patryk 建议的那样在数据库端进行任何过滤,那么它应该很容易测试和修复

标签: c# linq entity-framework


【解决方案1】:

它很慢,因为您不再在数据库中进行查询,而是在内存中进行查询。它从PageElements 表中提取所有数据,然后在内存中对其进行过滤。原因是您使用的是Func&lt;&gt; 委托,这会强制LINQ 使用Enumerable 而不是Queryable。要解决此问题,请改用 Expression&lt;Func&lt;&gt;&gt;

但我建议不要尝试按照您的方式编写查询。它使查询更难阅读和微调。特别是如果您希望从中产生某种 SQL。

也许你可以通过扩展方法做到这一点:

// needs to be in static class
public static IQueryable<PageElement> TypeCheck(this IQueryable<PageElement> q, byte? typeElement){
    return q.Where(pe=>pe.TypeID == t); // also this might not work is typeElement is null
}

那么你可以称它为

ObjectContext.PageElement.TypeCheck(typeElement).ToList(); // etc..

【讨论】:

  • 谢谢!如何在 Where 调用中使用 Expression>?
  • @jimmyjambles 我敢肯定,按照您编写查询的方式进行操作会很困难。把所有东西放在一起,它应该可以正常工作。尝试搜索 LINQ 并撰写。您可能会知道如何正确执行此操作。
  • 在我的代码中有很多地方我使用了不同谓词的不同组合,在这个例子中我只使用了 4,但我经常调用更多,我想保留它们在同一个地方,我可以使用 Expression> 适用于前 2 个谓词,但似乎无法为需要参数的谓词获得正确的语法
  • @jimmyjambles 我唯一可以推荐的:stackoverflow.com/search?q=linq+compose
  • @Euphoric,你能看看这个看看有什么问题吗 - stackoverflow.com/questions/27807879/…
猜你喜欢
  • 2022-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多