LINQ查询性能问题

时间:2013-11-05 14:15:30

标签: 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;

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

1 个答案:

答案 0 :(得分: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
}

然后你可以把它称为

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