Linq如何根据父项的属性查询子集合的组合列表的项列表

本文关键字:列表 子集合 组合 查询 属性 Linq 何根 | 更新日期: 2023-09-27 18:19:43

嗨,说我有对象:

public class InvoiceLine
{
}

public class InvoiceHeader
{
    public char Group { get; set; }
    public List<InvoiceLine> InvoiceLines { get; set; }
}

数据设置如下:

var invoiceLine1 = new InvoiceLine();
var invoiceLine2 = new InvoiceLine();
var invoiceLine3 = new InvoiceLine();
var invoiceLine4 = new InvoiceLine();
var invoiceLine5 = new InvoiceLine();
var invoiceLine6 = new InvoiceLine();
var invoiceLine7 = new InvoiceLine();
var invoiceLine8 = new InvoiceLine();
var invoiceHeader1 = new InvoiceHeader { Group = 'A', InvoiceLines = new List<InvoiceLine> { invoiceLine1, invoiceLine2 } };
var invoiceHeader2 = new InvoiceHeader { Group = 'A', InvoiceLines = new List<InvoiceLine> { invoiceLine3, invoiceLine4 } };
var invoiceHeader3 = new InvoiceHeader { Group = 'B', InvoiceLines = new List<InvoiceLine> { invoiceLine5, invoiceLine6 } };
var invoiceHeader4 = new InvoiceHeader { Group = 'B', InvoiceLines = new List<InvoiceLine> { invoiceLine7, invoiceLine8 } };
var invoiceHeaders = new List<InvoiceHeader>
{
    invoiceHeader1,
    invoiceHeader2,
    invoiceHeader3,
    invoiceHeader4
};

我想要得到的是每个组的invoiceLines列表。

所以我想参加A组:

invoice1invoice2invoice3invoice4

B组:

invoice5invoice6invoice7invoice8

我得到的最远的是:

var invoiceLinesGroupA = invoiceHeaders.SelectMany(x => x.InvoiceLines);

据我所知,它将获得全部八条invoiceLine。不知怎的,我需要按组来区分,只得到A组的,对B组也一样。

有人能帮忙吗?

Linq如何根据父项的属性查询子集合的组合列表的项列表

您可能只想按以下组对发票头进行分组:

var groups = invoiceHeader.GroupBy(ih => ih.Group);

然后您可以访问组的行:

foreach(var group in groups)
{
    Console.WriteLine("Group " + group.Group);
    Console.WriteLine("Lines:");
    Console.WriteLine(string.Join(", ", group.SelectMany(h => h.InvoiceHeader.InvoiceLines)));
}

输出将类似

Group A
Lines:
invoice1, invoice2, invoice3, invoice4
Group B
Lines:
invoice5, invoice6, invoice7, invoice8

看看Enumerable.SelectMany 的过载

var result = invoiceHeaders
               .SelectMany(x => x.InvoiceLines,
                           (group, InvoiceLine)=>{group, InvoiceLine})
               .Where(res => res.group='A');

这应该做到:

        var test = from h in invoiceHeaders
                   from i in h.InvoiceLines
                   group i by h.Group
                   into g
                   select new {key = g.Key, rows = g.ToArray()};

然后,您可以访问类似test.Where(x => x.key == 'A').rows 的项目

var q = from current in myInvoiceHeaders
                join c in myInvoiceLines on current.Id equals c.Header.Id into linesByHeader                    
                select new {
                    Header = current,
                    Lines = linesByHeader
                };

应该在您有加入这两个实体的标准的前提下工作。

var regrouped = invoiceHeaders
    .SelectMany(
        header => header.InvoiceLines,
        (header, line) => new { header, line }
    )
    .GroupBy(
        o => o.header.Group,
        o => o.line,
        (groupName, lines) => new InvoiceHeader
        {
            Group = groupName,
            InvoiceLines = lines.ToList()
        }
    )
    .ToList();