我可以在Breeze.js中进行显式加载吗?

我可以在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的联接。

在实体框架中,我们可以使用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效率可能会更低

为了提高效率,我们可以使用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应该为其提供客户端支持。