2015-11-01 49 views
0

我正在使用实体框架,并且与它相当新。实体框架中的FK对象 - 执行问题

我有一个表名为:Order and table named:Products。

每个订单都有很多产品。

当生成实体时,我得到了具有ICollection对象的Order对象。

的问题是我有很多的产品,每个订单(20K),当我做

order.Products.where(......) 

的EF运行SELECT语句只与订单ID = 123并执行其中的其余部分码。

因为我有很多结果 - 选择需要很多时间。我怎样才能更改代码 - 数据库中的选择将与where条件?

+0

。其中(......)将返回一个IQueryable,并且只有在实际触及其中一个对象或评估其中的任何对象时,才会执行该查询。只要你留在上下文中,这应该不成问题。 – DevilSuichiro

回答

1

此语句:

var prods = order.Products.Where(...); 

相当于:

var temps = order.Products; 
var prods = temps.Where(...); 

不同于Where(...),它返回一个IQueryableorder.Products触发迟缓装载,这产生一个ICollection和将被立即执行的,而不是延迟。所以这是生成你所看到的select语句的order.Products部分。它将属于该订单的所有产品提取到内存中。然后Where(...)部分在内存中执行,因此性能不佳。

要避免这种情况,只有在确实需要订单上的所有产品时,才应使用order.Products。如果你想只是其中的一个子集,这样做如下:

ctx.Products.Where(prod => prod.Order.Id == order.Id && ...) 

注意ctx是数据库方面,而不是order对象。

如果你认为上面的prod.Order.Id == order.Id条款看起来有点脏,这里有一个更纯净,但较长的替代:

ctx.Entry(order).Collection(ord => ord.Products).Query().Where(...) 

产生完全相同的SQL查询。