我正在使用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 - 但是如何将它们再次映射到实体对象?)
由于
答案 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()
方法。)