繁体   English   中英

使用 LINQ 将记录展平到父/子对象。 无重复数据

[英]Flattened records to parent/child objects using LINQ. Without duplication of data

我正在尝试使用 LINQ 更好地理解分组。 我想收集一组扁平记录并将它们转换为父/子关系中的两个对象集合。 在我的示例中,扁平记录包含在 ImportedExpenses 类中,而 Expense/ExpenseLineItem 类分别形成父/子关系。

public class ImportedExpense {
    public string EmployeeName {get; set;}
    public string CustomerName {get; set;}
    public DateTime ExpenseDate {get; set;}
    public Decimal Amount {get; set;}
    public string Description {get; set;}
}

public class Expense {
    public string EmployeeName {get; set;}
    public string CustomerName {get; set;}
    public List<ExpenseLineItem> LineItems {get; set;}
}

public class ExpenseLineItem {
    public DateTime ExpenseDate {get; set;}
    public Decimal Amount {get; set;}
    public string Description {get; set;}
}

过去,我通过重复 ExpenseLineItem 类中的信息来实现这一点。

public class ExpenseLineItem {
    public string EmployeeName {get; set;}
    public string CustomerName {get; set;}
    public DateTime ExpenseDate {get; set;}
    public Decimal Amount {get; set;}
    public string Description {get; set;}
}

我将使用以下 LINQ 语句,其中importedDataImportedExpense类型的集合

var expenseCollection = importedData.GroupBy(x => 
    new 
    {
        x.EmployeeName,
        x.CustomerName
    })
    .Select (y => new Expense()
    {
        EmployeeName = y.Key.EmployeeName,
        CustomerName = y.Key.CustomerName,
        LineItems = y.ToList();
    });

但是,我想完成同样的事情,而不必重复 Expense 和 ExpenseItem 类中的信息。

我将如何形成 LINQ 查询来完成此操作? 如果可能的话,使用流畅的语法,因为我对它与查询语法更熟悉。

我不确定我是否正确理解了您的问题,但是如果您想将ImportedExpense转换为Expense->ExpenseLineItem的层次结构,那么您的代码就差不多了。 尝试这个:

var expenseCollection = importedData.GroupBy(x => 
    new 
    {
        x.EmployeeName,
        x.CustomerName
    })
    .Select (y => new Expense()
    {
        EmployeeName = y.Key.EmployeeName,
        CustomerName = y.Key.CustomerName,
        LineItems = y.Select(ie => new ExpenseLineItem()
        {
            ExpenseDate = ie.ExpenseDate,
            Amount = ie.Amount,
            Description = ie.Description
        }).ToList();
    });

有一个GroupBy扩展,可让您对分组项目进行投影。 您可以使用它来投影按匿名类型分组的ExpenseLineItem和其中的其他数据点。

在代码中它看起来像这样:

var expenseCollection = importedData
    .GroupBy
    (
        x => new { x.EmployeeName, x.CustomerName },
        x => new ExpenseLineItem
        {
            ExpenseDate = x.ExpenseDate,
            Amount = x.Amount,
            Description = x.Description
        }
    )
    .Select
    (
        y => new Expense
        {
            EmployeeName = y.Key.EmployeeName,
            CustomerName = y.Key.CustomerName,
            LineItems = y.ToList()
        }
    );

或者,您可以在选择中进行投影:

var expenseCollection = importedData
    .GroupBy(x => new { x.EmployeeName, x.CustomerName })
    .Select
    (
        y => new Expense
        {
            EmployeeName = y.Key.EmployeeName,
            CustomerName = y.Key.CustomerName,
            LineItems = y.Select
            (
                item => new ExpenseLineItem
                {
                    ExpenseDate = item.ExpenseDate,
                    Amount = item.Amount,
                    Description = item.Description
                }
            ).ToList()
        }
    );

您可以将投影移出到单独的方法或强制转换运算符,但我认为上面的内容非常透明。

暂无
暂无

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

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