Как получить коллекцию дочерних элементов, применяющих фильтры как к родительским, так и к дочерним элементам

#c# #nhibernate #list #lambda

#c# #nhibernate #Список #лямбда

Вопрос:

Я использую NHibernate для извлечения коллекции заказов (и ее строк заказов) из базы данных Sql Server.

Это мой класс ShipmentOrder:

 public class ShipmentOrder
{
        private ICollection<ShipmentDetail> _ShipmentsDetails;

        public virtual ReadOnlyCollection<ShipmentDetail> ShipmentsDetails
        {
            get { return (new List<ShipmentDetail>(_ShipmentsDetails).AsReadOnly()); }
        }   
}
  

NHibernate возвращает IList со всеми загруженными деталями (ShipmentsDetails) (поскольку я хочу их загрузить).

Теперь я хотел бы отфильтровать свою коллекцию ShipmentOrder и ShipmentDetail и получить обратно коллекцию ShipmentDetail.

Я пробовал что-то вроде этого:

 IList<ShipmentOrder> Results;

// Fetch orders using nHibernate
Results = FetchOrders();

var shipmentLines = Results
    .Where(x => x.Company == "XXX" amp;amp; x.OrderNumber == "111")
    .SelectMany(x => x.ShipmentsDetails)
    .Where(s => s.RowNumber == 1 amp;amp; s.RowSeq == 0)
    .ToList();
  

Но я понял, что получаю несколько результатов одной и той же строки.

Я преобразовал выражение lamda следующим образом:

 var shipmentLines = Results
    .Where(x => x.Company == "XXX" amp;amp; x.OrderNumber == "111")
    .SelectMany(x => x.ShipmentsDetails)
    .Where(s => s.RowNumber == 1 amp;amp; s.RowSeq == 0)
    .Distinct()
    .ToList();
  

и это работает нормально.
Мне было интересно, есть ли лучший способ добиться того же результата без distinct.

Обновить:

Я использую SelectMany здесь, потому что это единственный способ, который я нашел, применить фильтры к дочерним элементам (ShipmentsDetails).

Комментарии:

1. Вы хотите получить отдельный список без использования Distinct ?

2. @Jamiec: Ну, пример кода, который я включил, должен возвращать одну строку, но я получаю 4 строки, потому что есть 4 порядка. Я использую SelectMany, потому что это единственный способ, который я нашел для применения фильтров к дочерней коллекции.

3. x => x.Company == "XXX" amp;amp; x.OrderNumber == "111" Идентифицирует ли один ShipmentOrder ? если да, то s.RowNumber == 1 amp;amp; s.RowSeq == 0 идентифицирует ли один ShipmentLine ? Каков ваш ожидаемый результат от этого запроса?

4. это похоже на Linq2Objects, поэтому результаты IList содержат повторяющиеся записи, вероятно, вы выполняете быструю выборку до глубоких уровней, что, к сожалению, приводит к дублированию корневых объектов. используйте distinctrootentity-resulttransformer в запросе

5. @Firo: вы были абсолютно правы. Я не думал об этом. Отлично. Если вы откроете ответ, я закрою ваш.

Ответ №1:

это похоже на Linq2Objects, поэтому результаты IList содержат повторяющиеся записи, вероятно, вы выполняете быструю выборку до глубоких уровней, что, к сожалению, приводит к дублированию корневых объектов. используйте distinctrootentity-resulttransformer в запросе