在Entity Framework中,我们可以通过使用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的连接。因此,结果行的宽度约等于四个表的组合宽度。如果所有条目具有大约相同数量的列,则查询将返回比其必须大约四倍的有效负载。如果我们查询更深层次,那么生成的SQL效率会更低。
为了提高效率,我们可以使用Explicit Loading和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查询将映射到服务器上的Explicit Loading并导致更高效的查询,如上面的EF Eager Loading示例中所示?也许这可以通过合并完成,但我不知道该怎么做。
答案 0 :(得分:0)
也许我误解了你的问题但是当你说查询的包含版本的有效载荷大于使用显式加载的版本时,我假设你在谈论从数据库到服务器的有效载荷和不是从服务器到breeze客户端。 breeze客户端的有效负载将是相同的。
但是,那说,如果你真的想使用显式的Eager加载,那么我能想到的唯一方法是重写你的服务器查询,这样它就不再返回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 });
我实际上没有测试过这个,但我认为它会起作用。