Linq to entities - 如何在entitycollection上选择where条件的实体?

时间:2010-10-12 12:53:59

标签: entity-framework linq-to-entities one-to-many eager-loading entitycollection

我发现有几次人们要求同样的问题,但似乎答案永远不会令人满意,尽管它应该很容易(理论上)。这是我的问题:

我有一个名为“公司”的实体,其中我有一个entityCollection“Employees”(一对多)。我需要检索所有公司,对于每个公司,我只想要年龄超过21岁的员工。

我试过了:

Return context.Companies.Include("Employees").Where(c => c.Employees.Where(e => e.Age > 21).Count() > 0)

这不起作用,因为它给了我每个公司的所有员工,如果至少有一个超过21(实际上是.Any())

我试过了:

Return context.Companies.Include("Employees").Select(c => New Company {  
.Id = c.Id, 
.Employees = c.Employees.Where(Function(e) e.Age > 24)
}).ToList()

这也不起作用(虽然它本来是完美的),但它给了我以下错误:实体或复杂类型'MyModel.Company'不能在LINQ to Entities查询中构造。

如何选择我所有的公司,每个公司只有21岁以上的员工?目前,我选择所有并在客户端,我过滤我的员工,但我不喜欢这个解决方案。

有人能帮助我吗?


谢谢Morteza Manavi-Parast,它会做的工作!

尽管如此,我很难说服自己,在一个独特的查询中这样做并没有在Entity框架中实现。这是一个相对常见的情况......作为证明,在这个论坛上有很多类似我的问题。

我很惊讶......也许是为了下一个版本?


要清楚,我需要一个公司列表,因为我直接将查询结果绑定到数据网格。为了您的信息,当我点击我的数据网格的一行(所以选择一家公司)时,我有第二个Grid,其中填充了来自entityCollection的员工(21岁以上)。

3 个答案:

答案 0 :(得分:2)

您是否尝试选择新的匿名类型,而不是使用公司类型:

Return context.Companies.Include("Employees").Select(c => New With {
    .Id = c.Id,
    .Employees = c.Employees.Where(Function(e) e.Age > 24)
}).ToList()

(对不起,如果语法稍微偏离,我已经有一段时间了,因为我已经在VB.NET中完成了LINQ /匿名类型)

答案 1 :(得分:2)

在LINQ to Entities中无法使用include进行“有条件的预先加载”。虽然存在2种解决方法。第一个是 Filtered Projection ,它是Justin建议的那个,但在所有情况下都可能不合适,因为它提供了一组匿名类型对象。

第二种方式称为 两个跟踪查询 ,它为您提供了一系列强类型公司,其员工满足条件,我相信您正在寻找的。这是代码:

var companies = context.Companies.ToList();
var employees = context.Employee.Where(e => e.Age > 21);
foreach (var employee in employees) {
   companies.Single(c => c.CompanyID == employee.CompanyID).Employees.Add(employee);
}

请查看Conditional Eager Loading以获取其他示例。

答案 2 :(得分:1)

你可能会过度思考这个问题。如果您有公司=>员工关系双向映射,然后只需在Employee上选择where子句并包含公司。

Return context.Employee.Include("Company").Where(e => e.Age > 21)
相关问题