当您在Linq-to-SQL中查询模型对象上的EntitySet属性时,它将返回实体集中的所有行,并进一步查询客户端。
这已在网上的几个地方得到证实,我自己也观察到了这种行为。 EntitySet不实现IQueryable。
我必须做的是转换代码,如:
var myChild = ... ;
// Where clause performed client-side.
var query = myChild.Parents().Where(...) ;
为:
var myChild = ... ;
// Where clause performed in DB and only minimal set of rows returned.
var query = MyDataContext.Parents().Where(p => p.Child() == myChild) ;
有谁知道更好的解决方案?
第二个问题:这是在实体框架中修复的吗?
答案 0 :(得分:5)
EntitySet只是实体的集合。它实现IEnumerable,而不是IQueryable。 Active Record模式指定实体直接负责自己的持久性。 OR映射器实体不具有持久层的任何直接知识。或者Mappers将此职责以及工作单元和身份映射职责放入数据上下文中。因此,如果需要查询数据源,则必须使用上下文(或Table对象)。要改变这种情况会使使用中的模式变得弯曲。
答案 1 :(得分:0)
我遇到了类似的问题:How can I make this SelectMany use a join。在弄乱LINQPad很长一段时间后,我发现了一个不错的解决方法。关键是推送您正在查看内部的实体集,一个SelectMany,Select,Where等。一旦进入它内部,它就变成了一个表达式,然后提供者可以把它变成一个正确的查询。
使用您的示例尝试:
var query = from c in Children
where c == myChild
from p in c.Parents
where p.Age > 35
select p;
我无法100%验证此查询,因为我不知道您的模型的其余部分。但是查询的前两行导致其余部分成为提供者变为连接的表达式。这适用于我自己的例子,该例子与上面的问题有关。