Чтобы резюмировать комментарии, в настоящее время ваш запрос использует Внутреннее объединение для связи 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(),
});