简体   繁体   English

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

[英]Linq how to query a list of items for a combined list of a child collection based on a property of the parent item

Hi say I have the objects: 嗨,我有一些东西:

public class InvoiceLine
{
}

and

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

Data is set up for them as follows: 为他们设置数据如下:

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
};

What I want to get is a Lists of invoiceLines for each Group. 我要获取的是每个组的发票行列表。

So I would like for group A: 所以我想为A组:

invoice1 , invoice2 , invoice3 and invoice4 invoice1invoice2invoice3invoice4

and for group B: 对于B组:

invoice5 , invoice6 , invoice7 and invoice8 invoice5invoice6invoice7invoice8

The furthest I got was: 我最远的是:

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

which as far as I can tell will get all eight invoiceLines. 据我所知,它将获得全部八个invoiceLines。 Somehow I need to discrimate by group to just get the ones for groupA and do likewise for groupB. 我需要以某种方式对组进行区分,以便仅对groupA进行区分,对groupB同样进行区分。

Can anyone help with this? 有人能帮忙吗?

You may just want to group the invoice headers by the group: 您可能只想按组将发票抬头分组:

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

Then you can access the lines of the groups: 然后,您可以访问组的行:

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

Output would be something like 输出将类似于

Group A
Lines:
invoice1, invoice2, invoice3, invoice4

Group B
Lines:
invoice5, invoice6, invoice7, invoice8
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();

Look at this overload of Enumerable.SelectMany 查看此Enumerable.SelectMany重载

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

This should do it: 应该这样做:

        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()};

You can then access the items like this test.Where(x => x.key == 'A').rows 然后您可以访问类似此test.Where(x => x.key == 'A').rows的项目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
                };

should work under the premise that you have a criteria to join both entities. 应该在您有加入两个实体的条件的前提下工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM