2012-03-11 36 views
0

我正在使用EF4。有2个实体: 人{Name} Hobbys {Person.Name,IsCoolHobby} 1人可以有几个hobbys。LINQ2Entity中一对多的嵌套位置

我现在有

IQueryable<Person> p; 
p = container.PersonSet.Include("Hobbys").AsQueryable(); 
p = p.Where(x => x ?????); 
List<Person> tmp = p.ToList(); 

我怎么只能返回谁拥有酷hobbys(IsCoolHobby ==真)这些人士?我想加入,但我无法将它们加载到列表(选择只能返回的人,业余爱好或新的类型 - 但如何实体再次反对将它们映射?)

感谢

回答

2

哪有我只返回那些有酷酷的人(IsCoolHobby == true)?

List<Person> tmp = container.PersonSet.Include("Hobbys") 
    .Where(p => p.Hobbys.Any(h => h.IsCoolHobby)) 
    .ToList(); 

这将加载谁至少有一个很酷的爱好,但Hobbys收集那些人总是包含所有 hobbys,也是酷hobbys的人。

编辑

不幸的是过滤和预先加载(Include)期间分拣孩子目前不支持。有一个request on the EF feature suggestion page for this feature。该请求的状态为“正在审查”,因此希望将来可能会实施。 (大概未来:至少约5 EF(测试版),MSDN上的第一个文件说有过滤/排序明确规定,预先加载仍然没有实现。)

现在只有两个解决方法。首先是使用的投影:

var projectedData = container.PersonSet 
    .Where(p => p.Hobbys.Any(h => h.IsCoolHobby)) 
    .Select(p => new 
    { 
     Person = p, 
     CoolHobbys = p.Hobbys.Where(h => h.IsCoolHobby) 
    }) 
    .ToList(); 

结果是包含谁拥有凉爽hobbys和那些很酷的hobbys的收集用户的匿名对象的集合。如果您不禁用更改跟踪(通过对查询使用NoTracking选项),则该人员的hobbys集合应该自动填充结果。

第二个选择是使用具有CreateSourceQuery “明确的” 加载:

List<Person> tmp = container.PersonSet 
    .Where(p => p.Hobbys.Any(h => h.IsCoolHobby)) 
    .ToList(); 
foreach (var person in tmp) 
{ 
    person.Hobbys.Attach(person.Hobbys.CreateSourceQuery() 
     .Where(h => h.IsCoolHobby).ToList()); 
} 

有两点需要注意这里:

  • CreateSourceQuery仅在EntityCollection S,即用如果您正在使用EntityObject派生实体。它不适用于EF 4.0中的POCO实体。 (EF> = 4.1/DbContext也可以为POCO选择明确加载 - >Query()方法。)
  • 上面的代码表示数据库的1 + N往返行程:第一个用于没有hobbys的人员集合,然后是一个附加每个人查询加载酷酷游戏。
+0

非常感谢。是否有可能加载所有人,只有酷酷的人(对不起没有指定适当的人) 假设人至少有一个爱好 – damike 2012-03-12 07:21:11

+0

@damike:请参阅我上面的编辑。 – Slauma 2012-03-12 19:10:02

+0

非常感谢您的好解释:-) – damike 2012-03-13 12:29:16