我可以在Breeze.js中进行显式加载吗?
在实体框架中,我们可以使用Include加载一行实体及其关联实体 例如,假设实体A与实体B、C和D之间存在一对多关系:我可以在Breeze.js中进行显式加载吗?,breeze,Breeze,在实体框架中,我们可以使用Include加载一行实体及其关联实体 例如,假设实体A与实体B、C和D之间存在一对多关系: var a = context.A .Where(a => a.Id == 7) .Include(a => a.B) .Include(a => a.C) .Include(a => a.D) .Single(); 但是,这样的查询可能效率低下。例如,在本例中,我们生成一个SQL查询,返回a与B、C和D的联接。
var a = context.A
.Where(a => a.Id == 7)
.Include(a => a.B)
.Include(a => a.C)
.Include(a => a.D)
.Single();
但是,这样的查询可能效率低下。例如,在本例中,我们生成一个SQL查询,返回a与B、C和D的联接。因此,结果行的宽度大约等于四个表的组合宽度。如果所有条目的列数大致相同,则查询将返回一个约为其必须大小四倍的有效负载。如果我们进行更深层次的查询,生成的SQL效率可能会更低
为了提高效率,我们可以使用Load()方法显式加载。比如说,
var a = context.A
.Where(a => a.Id == 7)
.Single();
var b = context.Entry(a).Collection(a => a.B).Load().ToList();
var c = context.Entry(a).Collection(a => a.C).Load().ToList();
var d = context.Entry(a).Collection(a => a.D).Load().ToList();
这将映射为四个单独的查询,返回与以前相同的总行数,但宽度为原来的四分之一
在Breeze.js中,.expand()映射到服务器上的.Include()。所以我用
var query = breeze.EntityQuery
.from("A")
.where("Id", "==", 7)
.expand("B, C, D");
但是,是否有任何Breeze.js查询会映射到服务器上的显式加载中,并像上面的EF-Eager加载示例那样产生更高效的查询?也许这可以通过合并实现,但我不确定如何实现。也许我误解了你的问题,但当你说查询的include版本比使用显式加载的版本有更大的负载时,我假设您讨论的是从数据库到服务器的负载,而不是从服务器到客户端的负载。到breeze客户端的有效负载将是相同的 但是,也就是说,如果您真的想使用显式的即时加载,那么我能想到的唯一方法就是像这样重写您的服务器查询,使其不再返回IQueryable,然后在服务器上强制执行即时收集
[HttpGet]
public A EagerA(id) {
var a = context.A
.Where(a => a.Id == 7)
.Single();
var b = context.Entry(a).Collection(a => a.B).Load().ToList();
var c = context.Entry(a).Collection(a => a.C).Load().ToList();
var d = context.Entry(a).Collection(a => a.D).Load().ToList();
return a;
}
这也意味着您必须将客户端更改为使用“withParameters”而不是“where”方法,即
var query = breeze.EntityQuery
.from("A")
.withParameters( { id: 7 });
我还没有实际测试过,但我认为它会起作用。谢谢Jay,效果很好。我想主要的一点是,数据库服务器和web服务器之间的数据传输效率不如web服务器和客户端之间的重要,因为带宽和延迟有几个数量级的差异。尽管如此,如果出现前一种情况很重要,知道有一种解决方法还是很好的。在系统负载很重的情况下,显式加载可能很重要。也许Breeze应该为其提供客户端支持。