0

在 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 效率会更低。

为了提高效率,我们可以使用显式加载和 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 Loading 示例中所示?也许这可以使用合并来完成,但我不知道该怎么做。

4

1 回答 1

0

也许我误解了您的问题,但是当您说查询的包含版本比使用显式加载的版本具有更大的有效负载时,我假设您是在谈论从数据库到服务器而不是从服务器到微风客户端。无论哪种方式,微风客户端的有效负载都是相同的。

但是,就是说,如果您真的想使用显式急切加载,那么我能想到的唯一方法就是像这样重写您的服务器查询,以便它不再返回 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 });

我还没有实际测试过,但我认为它会起作用。

于 2013-03-16T02:11:54.043 回答