Linq toEntity - 如何在实体集合上选择具有 where 条件的实体?

发布于 2024-09-27 02:37:38 字数 1019 浏览 7 评论 0原文

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

我有一个名为“公司”的实体,其中有一个实体集合“员工”(一对多)。我需要检索所有公司,对于每个公司,我只想要年龄大于 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,它会完成工作!

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

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


需要明确的是,我需要一个公司列表,因为我将查询结果直接绑定到数据网格。供您参考,当我单击数据网格的一行(因此选择一家公司)时,我有第二个网格,其中填充了来自实体集合的员工(21 岁以上)。

I found several times people asking for the same question but it seems that the answer was never satisfying altough it should be pretty easy (in theory). Here is my question :

I have an entity called "Company" inside which I have an entityCollection "Employees" (one to many). I need to retrieve all Companies and for each of them, I only want the employees with an Age greater than 21.

I tried :

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

That doesn't work as it gives me all employees for each company if there is at least one above 21 (it is actually the same than .Any() )

I tried :

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

That didn't work either (although it would have been perfect), it gives me the following error : The entity or complex type 'MyModel.Company' cannot be constructed in a LINQ to Entities query.

How can you select all my companies with only, for each of them, the employees being above 21 ? At the moment, I select all and on the client side, I filter my employees but I don't like that solution.

Can anybody help me ?


Thank you Morteza Manavi-Parast, it will do the work !

Nevertheless, I hardly convince myself that doing so in a unique query has not be implemented in the Entity framework. It is such a relatively common situation ... As a prove, there are numbers of questions like mine on this forum.

I am surprised ... Maybe for the next release ?


To be clear, I need a list of Companies as I am directly binding the result of my query to a datagrid. For your information, when I click on a row of my datagrid (so selecting a company), I have a second Grid which is populated with its employees (above 21 years old) coming from the entityCollection.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吖咩 2024-10-04 02:37:39

无法在 LINQ to Entities 中包含“条件预加载”。不过,有两种解决方法。第一个是过滤投影,这是 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);
}

请查看条件预加载 另一个例子。

There is no way to have a "Conditional Eager Loading" with include in LINQ to Entities. There are 2 workarounds exist though. The first one is Filtered Projection and it's the one that Justin suggested but might not be desirable in all situations as it gives a collection of anonymous type objects.

The second way is called Two Tracked Queries which gives you a collection of strongly types Companies whose their employees satisfy a condition and I believe that's what you are looking for. Here is the code for it:

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

Please take a look at Conditional Eager Loading for another example.

雨轻弹 2024-10-04 02:37:39

您是否尝试过选择新的匿名类型而不是使用 Company 类型:(

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/匿名类型以来已经有一段时间了)

Instead of using the type Company, have you tried selecting a new anonymous type:

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

(Sorry if the syntax is a little off, it's been a while since I've done LINQ/Anonymous Types in VB.NET)

南渊 2024-10-04 02:37:39

这个问题你可能想多了。如果您有公司=>员工关系双向映射,然后只需使用 where 子句对员工进行选择并包含公司即可。

Return context.Employee.Include("Company").Where(e => e.Age > 21)

You might be over-thinking this one. If you have the Company => Employee relationship bi-directionally mapped, then just do the select on Employee with the where clause and include company.

Return context.Employee.Include("Company").Where(e => e.Age > 21)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文