LINQ查询性能问题

jim*_*les 4 c# linq entity-framework

我在方法语法中有以下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;
Run Code Online (Sandbox Code Playgroud)

我发现当ToList的调用花了很长时间,我想知道是否有任何我做错了导致性能下降.我此时只运行ToList作为测试,但只需要几秒钟就可以返回大约7000条记录.我怎样才能改善这个?

Eup*_*ric 9

它很慢,因为你不再在数据库中进行查询,而是在内存中查询.它从PageElements表中提取所有数据,然后在内存中过滤它.这样做的原因是你正在使用Func<>委托,这迫使LINQ使用Enumerable而不是Queryable.要修改此用途Expression<Func<>>.

但我建议不要试图按照你的方式编写查询.它使查询更难以阅读和微调.特别是如果你期望某种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
}
Run Code Online (Sandbox Code Playgroud)

然后你可以称之为

ObjectContext.PageElement.TypeCheck(typeElement).ToList(); // etc..
Run Code Online (Sandbox Code Playgroud)