我下面有一个查询,应该按ID,EntityName,DocType,管辖区对结果进行分组。对于每个组,查询还返回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()
};
最佳答案
为了回顾评论,当前您的查询使用Inner Join将NettingAgreementEntity
与NettingAgreementProduct
关联。这不仅会乘以结果集(因此需要您在之后使用GroupBy
),而且还会过滤掉没有NettingAgreementEntity
的NettingAgreementProduct
。
您可以通过切换到Group Join(或Left Outer Join + GroupBy
)来实现目标。
但是为什么要进入所有这些并发症。 EF导航属性使您几乎无需考虑手动联接,还可以轻松查看多重性,从而了解是否需要对结果进行分组。
因此,我建议将当前缺少的集合导航属性添加到您的NettingAgreementEntity
类中:
public class NettingAgreementEntity
{
// ...
public virtual ICollection<NettingOpinion> Opinions { get; set; }
}
(可选)对
NettingAgreementProduct
执行相同的操作,以防将来您需要类似的产品(这是多对多关系,应该可以从双方查询)。我还要将
NettingOpinion
类导航属性NettingAgreementProductNavigation
和NettingAgreementEntityNavigation
重命名为较短的名称,例如Product
和Entity
。这些名称(以及集合导航属性的名称)不影响数据库架构,但是IMHO提供了更好的可读性。了解这些内容后,您将看到所需的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(),
});