LINQ with Where and All не фильтрует данные - что не так с этим запросом? - PullRequest
2 голосов
/ 19 января 2012

Вот код, с которым у меня проблемы.Я использую 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, содержащий заказы, в которых есть как минимум один канадский получатель.В приведенном выше примере это были бы Order с OrderID = 00001 и 12355

. Код, похоже, не соответствует фильтрам Where и All, которые я пометил *,Возвращает все заказы.Пожалуйста, помогите мне понять, что я делаю не так.Огромное спасибо.

Ответы [ 2 ]

4 голосов
/ 19 января 2012

Я думаю, что вы хотите Any не All. Используя All, вы говорите, что все получатели заказа должны быть канадцами. Any выдаст вам заказы, в которых есть хотя бы один канадский получатель.

Еще одно предупреждение о All. Он не ищет все элементы для прохождения условия, он ищет первый элемент, который не соответствует условию. Следовательно, если у вас ноль предметов, у вас нет предметов, которые не соответствуют условию, и All всегда вернет true

2 голосов
/ 19 января 2012

Я бы объединил два запроса внутри цикла в один, а затем использовал бы 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 для пустой коллекции.

При объединении двух запросов весь запрос выполняется в базе данных, и AND должен вернутьправильный результат.

...