带有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 的订单

代码似乎不尊重我用*标记的WhereAll过滤器。它返回所有订单。请帮我理解我做错了什么。非常感谢。

带有Where和All的LINQ未筛选数据-此查询有什么问题

我想你想要的是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应该返回正确的结果。