1

我有几个表达式在 EF6 中运行 Count()。生成的 SQL 查询结束了一个有点复杂的查询,其中包含几个传入的参数。但是,如果我将 SQL 复制到 SSMS 中,它会在不到一秒的时间内运行。

在 EF 中,Linq 查询需要超过 30 秒,并且通常只是简单地引发连接超时异常。

查看活动监视器,我可以看到它似乎正在运行相同的查询数千次(如果不是数百万次)。

似乎有数十万次阅读

触发查询的代码由使用 LinqKit AsExpandable() 和 Invoke() 组合的几个表达式组成。

//properties is an IQueryable<Property> and checkDate a DateTime
int propertyCount = FilterCompliantOnDate(properties, checkDate).Count();



public IQueryable<Property> FilterCompliantOnDate(IQueryable<Property> properties, DateTime checkDate)
{
    // SelectedComplianceCategory is a local property (int?)
    return properties.AsExpandable().Where(p=>PropertyIsCompliant.Invoke(p, checkDate, SelectedComplianceCategory));
}



public static readonly Expression<Func<Property, DateTime, int?, bool>> PropertyIsCompliant = (p, checkDate, complianceCategory) =>
    CategoryComplianceRatings.Invoke(p, complianceCategory, checkDate).Any() &&
    CategoryComplianceRatings.Invoke(p, complianceCategory, checkDate)
        .All(cr => cr.ComplianceRating == ComplianceRating.Compliant);



private static readonly Expression<Func<Property, int?, DateTime, IQueryable<PropertyComplianceRating>>> CategoryComplianceRatings =
    (p, categoryId, checkTime) => p.ComplianceRatings.AsQueryable()
    .Where(cr =>
        cr.ComplianceCategory != null &&
        (
            categoryId == null ||
            (categoryId != null && cr.ComplianceCategory.Id == categoryId)
        )
    )
    .GroupBy(cr => cr.ComplianceCategory)
    .Select(g => g
    .Where(cr => cr.Date < checkTime)
    .OrderByDescending(cr => cr.Date)
    .FirstOrDefault()
);
4

2 回答 2

0

当您从不同的环境执行时,请检查会话设置(arithabort、ansi_nulls...)。确保它们都是一样的。很多时候,不同的设置会导致以完全不同的执行持续时间执行相同的过程。

于 2014-12-23T13:55:31.743 回答
0

也许您的查询正在跟踪所有引用,请以这种方式尝试AsNoTracking

database.Table.AsNoTracking().Where(e=>other code)

更新

如果它不起作用,请尝试将“AsQueryable()”移动到 Where 部分之后和 GroupBy 部分之前。

于 2014-12-23T13:20:29.407 回答