2012-07-21 58 views
3

我想要在单个查询中检索一组对象(A)和一些相关对象(B)。上有AB没有导航性能,所以我认为我需要使用这个语法:实体框架次要级别包含在投影中

select a from db.As where a.Id = x select new AndBHolder 
{ 
    A = a, 
    Bs = select b from db.Bs where b.ASomeId == A.SomeId select b 
} 

我不知道这是否是最好的方式,但它确实工作。但是,我现在需要包含BCs的列表)的属性。我没想到它的工作,但我想:

select a from db.As where a.Id = x select new AndBHolder 
{ 
    A = a, 
    Bs = select b from db.Bs.Include("Cs") where b.ASomeId == A.SomeId select b 
} 

从而未能与“法......包括宣布类型......不能与类型的实例调用...”。接下来,我想我会尝试的投影中的投影:

select a from db.As where a.Id = x select new AndBHolder 
{ 
    A = a, 
    Bs = select b from db.Bs where b.ASomeId == A.SomeId select new B 
     { 
      Id = b.Id, 
      // ... 
      Cs = select c from db.Cs where c.BId == b.Id select c 
     } 
} 

哪些失败,因为你不准投射到“不能在LINQ到实体查询来构造实体或复杂类型‘B’”一个映射对象。那么我如何检索Bs以及它们的Cs填充,还是仅仅不支持二级包含?我只需要对数据库进行两次调用,一次检索As,一个检索Bs及其Cs

回答

3

如果您使用select new的投影,您不能再使用Include,它将被忽略。相反,你必须添加相关实体的预测数据,例如:

var query = from a in db.As 
      join b in db.Bs on a.SomeId equals b.ASomeId into bGroup 
      where a.Id = x 
      select new AndBHolder 
      { 
       A = a, 
       Bs = bGroup, // Bs must be of type IEnumerable<B> 
       Cs = bGroup.SelectMany(bg => bg.Cs) // Cs is IEnumerable<C> 
      }; 

如果BC之间的关系是一个一对多的(不是很多对多)EF应填充Cs集合自动加载B(这就是所谓的“关系修正”),这意味着您可以在数据从数据库加载数据后从投影中丢弃Cs。为了把这个在一起,你可以尝试编写查询,像这样:

var query = (from a in db.As 
      join b in db.Bs on a.SomeId equals b.ASomeId into bGroup 
      where a.Id = x 
      select new 
      { 
       A = a, 
       Bs = bGroup, 
       Cs = bGroup.SelectMany(bg => bg.Cs) 
      }) 
      .AsEnumerable() // DB query gets executed here 
      .Select(y => new AndBHolder 
      { 
       A = y.A, 
       Bs = y.Bs // the Cs in every B should be populated here 
      }); 
+0

谢谢Slauma,我知道包括永远不会是答案,但我能看到我现在去错了...用成SelectMany已经解决了这个问题。 – 2012-07-21 20:42:56