带有Where和All的LINQ未筛选数据-此查询有什么问题
本文关键字:查询 问题 什么 数据 筛选 Where All LINQ 带有 | 更新日期: 2023-09-27 18:20:53
这是我遇到问题的代码。我使用的是从现有数据库中建模的EDMX。
// All orders completely shipped Grouped by RefId
var RefIdsWithAllShippedOrders = mydbcontext.OrderDetails
.Where(s => s.Application.CustomerID == "MSFT")
.GroupBy(o => o.RefId)
.Where(t => t.All(i => i.Status.Description.ToUpper() == "SHIPPED"))
.Select(g => g.Key);
// Iterate through the RefIds
foreach (var refid in RefIdsWithAllShippedOrders)
{
// Gather all the orders that have the same RefIds
var OrdersForThisRefid = (from o in mydbcontext.OrderDetails
where o.RefId == refid
select o).AsEnumerable();
//gather all the orders with at least one Canadian recipient
var orderswithcandianrecipients = from o in OrdersForThisRefId
where o.OrderRecipients.All( w=> w.Country.Trim().ToUpper() == "CANADA") // ****
select o;
// Print RefIds of the orders that have at least one Canadian recipient
foreach (var eachorder in orderswithcandianrecipients)
{
Console.WriteLine(eachorder.RefId);
}
}
这是我的模式:
订单详情
RefId OrderId (PK)
ABC001 00001
ABC001 00002
ABC001 00003
ABC002 00004
ABC002 12355
订单收件人
PK OrderID (FK) NAME COUNTRY
1 00001 LINCOLN USA
2 00001 JEFFERSON USA
3 00001 WASHINGTON CANADA
4 00001 FRANKLIN USA
5 00002 GRANT USA
6 00002 WILSON USA
7 12355 FORD CANADA
8 12355 JOHNSON USA
我希望得到的结果是var
类型,其中包含至少有一个加拿大收件人的订单。在上面的例子中,这将是OrderID=00001和12355 的订单
代码似乎不尊重我用*标记的Where
和All
过滤器。它返回所有订单。请帮我理解我做错了什么。非常感谢。
我想你想要的是Any
而不是All
。使用All
表示订单上的所有收件人都必须是加拿大人。Any
将为您提供至少有一个加拿大收件人的订单。
关于All
的另一个警告。它不查找通过条件的所有项,而是查找第一个未通过条件的项。因此,如果您有零个项目,则没有任何项目不符合条件,并且All
将始终返回true
我会将循环中的两个查询合并为一个查询,然后使用Any
,如cadrell0的回答所述:
var orderswithcandianrecipients =
from o in mydbcontext.OrderDetails
where o.RefId == refid && o.OrderRecipients.Any(
w => w.Country.Trim().ToUpper() == "CANADA")
select o;
问题似乎是在第一个查询中使用了AsEnumerable()
,导致数据加载到内存中。但是,因为查询中没有包含OrderRecipients
,所以该集合将为空。第二个查询在内存中执行(LINQ to Objects)。因此,All
将返回每个订单,因为对于空集合,它总是true
。用Any
替换它可能根本不会返回任何顺序,因为对于空集合,Any
总是false
。
通过组合这两个查询,整个查询在数据库中执行,ansd应该返回正确的结果。