[英]Very poor performance with a simple query in Entity Framework
所以我有一个非常简单的结构:
(现在不要介意愚蠢的结构,它就是这样的)。
所以现在我得到一个具有三个属性的对象列表:
我想要做的只是1)检查数据库中是否存在具有给定OrderNumber / Position -pair的RowExtra,如果存在,则2)更新Info-property。
我尝试了几种不同的方法来实现这一点,结果非常糟糕。 解决方案循环遍历对象列表并发出诸如的查询
myContext.RowExtras.Where(x => x.Position == currentPosition &&
x.OrderRow.Order.OrderNumber == currentOrderNumber)
或从另一边走
myContext.Orders.Where(x => x.OrderNumber == currentOrderNumber)
.SelectMany(x => x.OrderRows)
.SelectMany(x => x.RowExtras)
.Where(x => x.Position == currentPosition)
然后检查计数是否等于1,如果是,则更新属性,否则继续下一个项目。
我目前在数据库中有大约4000个RowExtras,需要更新其中一半。 这些方法使程序需要几分钟才能完成,这是不可接受的。 我不明白为什么需要这么长时间,因为返回所需RowExtra的SQL子句很容易手动编写(在where-part中只有2个连接和2个条件)。
我设法实现的最佳性能是使用看起来像这样的编译查询
Func<MyContext, int, string, IQueryable<RowExtra>> query =
CompiledQuery.Compile(
(MyContext ctx, int position, string orderNumber) =>
from extra in ctx.RowExtras
where
extra.Position == position &&
extra.OrderRow.Order == orderNumber
select extra);
然后为列表中的每个对象调用所述查询。 但即便采用这种方法也需要一分钟。 那么我如何在合理的时间范围内实现这一目标呢?
此外,我很抱歉这个过长的解释,但希望有人可以帮助我!
尽量减少数据库调用的次数。 根据经验,每个人至少需要大约10毫秒 - 即使只返回一个标量。
因此,通常,一次性获取您需要的所有数据,在代码中修改它然后保存它。
List<Order> orders = myContext.Orders
.Include( "OrderRows.RowExtras" )
.Where( ... select all the orders you want, not just one at a time ... )
.ToList();
foreach ( Order order in orders )
{
... execute your logic on the in-memory model
}
myContext.SaveChanges();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.