gpt4 book ai didi

c# - 让所有 parent 共有的 child

转载 作者:太空宇宙 更新时间:2023-11-03 19:39:40 24 4
gpt4 key购买 nike

我有以下使用 Entity Framework Core 的实体:

public class Parent {
public Int32 ParentId { get; set; }
public virtual Collection<ParentChildren> ParentChildrens { get; set; }
}

public class ParentChildren {
public Int32 ParentId { get; set; }
public Int32 ChildrenId { get; set; }
public virtual Parent Parent { get; set; }
public virtual Children Children { get; set; }
}

public class Children {
public Int32 ChildrenId { get; set; }
public virtual Collection<ParentChildren> ParentChildrens { get; set; }
public virtual Collection<ChildrenLocalization> ChildrenLocalizations { get; set; }
}

public class ChildrenLocalization {
public Int32 ChildrenId { get; set; }
public String Language { get; set; }
public String Name { get; set; }
public virtual Children Children { get; set; }
}

给定一个 IQueryable<Parent>我需要使用 Linq to Entities lambda 表达式:

  1. 获取所有父类共有的子类
  2. 对于每个 ChildrenChildrenLocalization得到它的名字与 Language="en" .

所以我尝试了以下方法:

var result = context.Parents
.SelectMany(y => y.ParentChildrens)
.GroupBy(y => y.ParentId)
.Where(y =>
context.Parents
.SelectMany(y => y.ParentChildrens)
.Select(z => z.ChildrenId)
.Distinct()
.All(z => y.Any(w => w.ChildrenId == z)))
.SelectMany(y => y)
.Select(y => new {
Id = y.ChildrenId,
Name = y.Children.ChildrenLocalizations.Where(z => z.Language == "en").Select(z => z.Name).FirstOrDefault()
})
.GroupBy(x => x.Id)
.Select(x => x.FirstOrDefault())
.ToList();

这个查询给出了预期的结果,但它看起来太复杂了。

我无法改进它,例如,我需要添加最后一个 GroupBy 才能使其正常工作。

如何使查询更简单?

最佳答案

由于您拥有多对多关系,因此最好将查询基于(开始)结果实体(Children),从而避免需要 GroupBy/Distinct 如果你从另一端开始它(Parent)。

如此给定

IQueryable<Parent> parents

假设您可以访问上下文,查询可以写成如下:

var query = context.Set<Children>()
.Where(c => parents.All(p => p.ParentChildrens.Select(pc => pc.ChildrenId).Contains(c.ChildrenId)))
.Select(c => new
{
Id = c.ChildrenId,
Name = c.ChildrenLocalizations.Where(cl => cl.Language == "en").Select(cl => cl.Name).FirstOrDefault()
});

这很好地转换为单个 SQL。

您从 unique Children 开始。对于要求 (2),您只需使用导航属性。要求 (1) 更复杂(all 总是比 any 更难实现),但我认为标准

parents.All(p => p.ParentChildrens.Select(pc => pc.ChildrenId).Contains(c.ChildrenId))

非常直观地表示所有 parent 共有的 child

关于c# - 让所有 parent 共有的 child ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55484202/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com