【发布时间】:2018-10-04 22:58:36
【问题描述】:
我有一个查询,它需要在每次调用时运行 300 多个循环。即使在新数据库上完成调用也需要大约 10 秒。 WebAPI 调用是不可接受的。
var isAbnormal = false;
var list = new List<String>();
//Check date range, log them & return if there is any abnormal.
foreach (DateTime day in DateHelper.EachDay(startDate, endDate))
{
var isActive = db.Operations.Any(x=>x.IsActive && x.Day == day);
var object;
var queryable = db.ObjectA.Where(x=>x.Day == day);
if(isActive){
queryable = db.ObjectA.First(x=>x.Day == day);
LogUtil.Info($"{object.Name}");
var isLogicACorrect = queryable.Any(x=>x.ObjectACount == 5);
var isLogicBCorrect = queryable.Any(x=>x.ObjectBCount == 3);
var isLogicCCorrect = queryable.Any(x=>x.ObjectCCount == 2);
var isLogicDCorrect = queryable.Any(x=>x.ObjectDCount == 8);
var isLogicECorrect = queryable.Any(x=>x.ObjectECount == 1);
if(!isLogicACorrect){
list.Add("Logic A is incorrect");
isAbnormal = true;
}
//More logic codes & db calls here, which is just to select & validate.
}
return list;
如何通过将所有查询合二为一来优化速度?除了一天之外,循环内容实际上是相同的。每个循环总共要调用 15 个查询,一个完整的循环中有 4500 个 db 查询。
【问题讨论】:
-
请多发些代码,你对
continue;有什么逻辑吗?我们需要查看更多内容以确定可以更改的内容 -
您应该首先获取给定日期范围内的所有活动操作,然后获取给定日期范围内的所有 ObjectA。获得该列表后,您可以从列表中查询,而不是每次都访问数据库。
-
我又加了一些,不过大部分都是多余的,只是为了检查数据库本身是否有当天的资源。
-
我确信逻辑可以大大优化,但是如果不查看真实代码,就不可能准确地评论如何最好地做到这一点。要优化 EF 查询,您需要考虑所涉及的实体、它们的关系以及您需要应用的所有计算/转换。
-
停止写代码,用代码思考。你到底想达到什么目的?用简单的英语陈述它,然后考虑解决方案,看看它是否有意义。如果是这样,请开始为您的解决方案编写代码。现在看看你的代码:
object是什么?你没有给它分配任何东西,你正在尝试LogUtil.Info($"{object.Name}");,为什么会这样?查看问题出在您的解决方案上。如果您无法用简单的英语解释您的解决方案(算法),请不要尝试编写代码。
标签: c# entity-framework entity-framework-6 asp.net-web-api2