如何基于LINQ中的嵌套属性协商联接和分组?

时间:2018-09-06 16:27:20

标签: c# linq sql-to-linq-conversion

所以我有一个像这样的嵌套数据结构:

public class ContractTerm
{
    public int ContractId { get; set; }
    public string SectionId { get; set; }
    public string SubsectionId { get; set; }
    public string TermId { get; set; }
    public int TermOrder { get; set; }
    public TermItem TermNavigation { get; set; }
}

public class TermItem
{
    public string SectionId { get; set; }
    public string SubsectionId { get; set; }
    public string TermId { get; set; }
    public string Text { get; set; }
    public ICollection<ContractTerm> ContractNavigation { get; set; }
}

我还有一个类以更友好的EF方式映射节/小节对(IRL,这是一个具有属性值和辅助函数的枚举,但是该类抽象了一些不必要的工作来重现问题) ):

public class Section
{
    public string Name { get; set; }
    public string SectionId { get; set; }
    public string SubsectionId { get; set; }
}

ContractTermTermItem在DbContext中都有自己的集合,我正在尝试为给定的{{ 1}}。我有以下课程可以包含它:

Section

我想选择ContractId的集合,并且有类似这样的内容:

public class TextsBySection
{
    public string SectionName { get; set; }
    public IEnumerable<string> Texts { get; set; }
}

这很好并且很花哨,但是它会为每个TextsBySection访问数据库。我觉得必须有一种使用public class ContractManager { //insert constructor initializing MyContext here private MyContext Context { get; } public IEnumerable<MyOutputClass> GetTerms(int contractId, IEnumerable<Section> sections) { Func<string, string, IEnumerable<string>> getBySection = (section, subsection) => context.ContractTerms.Include(x => x.TermNavigation) .Where(x => x.ContractId == contractId && x.SectionId == section && x.SubsectionId == subsection) .Select(x => x.TermNavigation.Text); var result = sections.Select(x => new MyOutputClass { SectionName = x.Name, Texts = getBySection(x.SectionId, x.SubsectionId) }).ToList(); return result; } } 和/或{{ 1}},使其只查询一次,但我看不到它。可能是这样的:

Section

如果所有这些都是用SQL编写的,那么选择必要的数据将很容易:

Join

...然后将结果分组到.NET中。但是我不明白如何做一个可以做同样事情的LINQ查询。

1 个答案:

答案 0 :(得分:2)

我改变了答案,好吧,我会做这样的事情……也许这可能对您有所帮助。

public static void Main(string[] args)
        {
            List<Section> sections = new List<Section>();
            List<ContractTerm> contractTerms = new List<ContractTerm>();
            List<TermItem> termItens = new List<TermItem>();

            //considering lists have records

            List<TextsBySection> result = (from contractTerm in contractTerms
                          join termItem in termItens
                              on new
                              {
                                  contractTerm.SectionId,
                                  contractTerm.SubsectionId,
                                  contractTerm.TermId
                              }
                              equals new
                              {
                                  termItem.SectionId,
                                  termItem.SubsectionId,
                                  termItem.TermId
                              }
                          join section in sections
                           on new
                           {
                               contractTerm.SectionId,
                               contractTerm.SubsectionId
                           } equals new
                           {
                               section.SectionId,
                               section.SubsectionId
                           }
                          select
                          new
                          {
                              sectionName = section.Name,
                              termItemText = termItem.Text
                          }).GroupBy(x => x.sectionName).Select(x => new TextsBySection()
                          {
                              SectionName = x.Key,
                              Texts = x.Select(i=> i.termItemText)
                          }).ToList();  
        }