我有几个表达式在 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()
);