Предложение Linq GroupBy, не включающее элементы с нулевым счетом - PullRequest
2 голосов
/ 08 мая 2019

У меня есть запрос ниже, который должен сгруппировать результат по Id, EntityName, DocType, Jurisdiction.Для каждой группы запрос также возвращает элементы ProductList.

В настоящее время, если группа содержит один или несколько продуктов, я могу видеть результат, выдавая группу с комбинацией Id, EntityName, DocType, Jurisdiction и ProductList, однако, если результат не содержитпродукты для определенной группы я не вижу группу вообще.То, что я хотел бы сделать, это показать группы, даже если в ее группе нет продуктов.Поэтому, если счетчик ProductList равен нулю, я хотел бы установить ProductList = новый список NettingAgreementProductDto.Любой вклад будет высоко оценен.

          var result = from nae in nettingAgreementEntities.Result
                     join no in nettingOpinions.Result 
                          on nae.EntityId equals no.EntityId 
                     join np in nettingProducts.Result 
                          on no.ProductId equals np.Id
                     group np by new 
                               { nae.EntityId, 
                                 nae.EntityName, 
                                 nae.DocType,
                                 nae.Jurisdiction 
                               } into g                      
                     select new NettingAgreementEntityDto
                     {
                         Id = g.Key.EntityId,
                         EntityName = g.Key.EntityName,
                         DocType = g.Key.DocType,
                         Jurisdiction = g.Key.Jurisdiction,
                         ProductList =  g.Select(x => new                                            
                                        NettingAgreementProductDto
                                        {
                                           Id = x.Id,
                                           Name = x.Name
                                        }).ToList()
                     };

1 Ответ

2 голосов
/ 09 мая 2019

Чтобы резюмировать комментарии, в настоящее время ваш запрос использует Внутреннее объединение для связи NettingAgreementEntity с NettingAgreementProduct s. Это не только умножает набор результатов (и поэтому требует использования GroupBy после), но также отфильтровывает NettingAgreementEntity без NettingAgreementProduct s.

Вы можете достичь цели, переключившись на Групповое объединение (или Левое внешнее объединение + GroupBy).

Но зачем вводить все эти осложнения. Свойства EF-навигации позволяют практически забыть о ручных объединениях, а также позволяют легко увидеть множественность, независимо от того, нужно ли группировать результат или нет.

Итак, я бы предложил добавить отсутствующее на данный момент свойство навигации по коллекции в ваш NettingAgreementEntity класс:

public class NettingAgreementEntity
{
    // ...
    public virtual ICollection<NettingOpinion> Opinions { get; set; }
}

При желании сделайте то же самое для NettingAgreementProduct на случай, если в будущем вам понадобится что-то похожее для продуктов (это отношение «многие ко многим», и его можно будет запрашивать с обеих сторон).

Также я бы переименовал NettingOpinion свойства навигации класса NettingAgreementProductNavigation и NettingAgreementEntityNavigation во что-то более короткое, например Product и Entity. Эти имена (а также имена свойств навигации по коллекции) не влияют на схему базы данных, но, по-моему, обеспечивают лучшую читаемость.

Как только вы это получите, вы увидите, что требуемый запрос LINQ - это вопрос простых Select, которые преобразуют класс сущности в DTO и позволяют транслятору запросов EF создавать необходимые объединения:

var result = db.Set<NettingAgreementEntity>()
    .Selec(nae => new NettingAgreementEntityDto
    {
        Id = nae.EntityId,
        EntityName = nae.EntityName,
        DocType = nae.DocType,
        Jurisdiction = nae.Jurisdiction,
        ProductList = nae.Opinions
            .Select(no => new NettingAgreementProductDto
            {
                no.Product.Id,
                no.Product.Name,
            }).ToList(),
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...