4

我在方法语法中有以下 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 条记录需要几秒钟。我该如何改进呢?

4

1 回答 1

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..
于 2013-11-05T14:17:54.167 回答