嵌套LINQ2Entity中1对多的位置

时间:2012-03-11 19:04:10

标签: entity-framework entity-framework-4 linq-to-entities

我正在使用EF4。有2个实体: 人{名} Hobbys {Person.Name,IsCoolHobby} 1人可以有几个爱好。

我现在有

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

我怎样才能只返回那些有很酷爱好的人(IsCoolHobby == true)?我尝试加入但我无法将它们加载到列表中(select只能返回Person,Hobby或new Type - 但是如何将它们再次映射到实体对象?)

由于

1 个答案:

答案 0 :(得分:2)

  

我怎样才能只返回那些有很酷爱好的人(IsCoolHobby   == true)?

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

这将加载至少有一个很酷的爱好的人,但Hobbys这些人的收藏总是包含所有爱好,也就是非酷的爱好。

修改

不幸的是,目前不支持在急切加载(Include)期间过滤和排序子项。有一个request on the EF feature suggestion page for this feature。该请求的状态为“正在审核”,因此希望将来可以实施该请求。 (可能未来:至少MSDN上关于EF 5(beta)的第一个文档明确表示仍未实现过滤/排序的急切加载。)

目前只有两种解决方法。第一种是使用投影:

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();

结果是一组匿名对象,其中包含一个有很酷的爱好者和一些​​酷酷的爱好者的用户。如果您未禁用更改跟踪(通过使用查询的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,即如果您使用的是EntityObject个派生实体。它不适用于EF 4.0中的POCO实体。 (EF&gt; = 4.1 / DbContext也可以选择显式加载POCO - &gt; Query()方法。)
  • 上面的代码表示数据库的1 + N往返:第一个没有hobbys的人员集合,然后是每人一个额外的查询来加载酷的hobbys。