【问题标题】:c# Merge List with another List based on keyc# 根据键将列表与另一个列表合并
【发布时间】:2014-07-11 23:57:30
【问题描述】:

我的主要对象是客户列表。由于我必须获取数据的方式,我需要合并两个列表,如下所示。余额清单包括所有客户的余额。基本上我想将与特定客户关联的余额添加到客户列表中。我正在尝试使用 Linq 根据它们的共同键 CustomerNumber 合并两者,但无法使其工作。

List<Customer> customers
List<Balance> balances

public class Customer
{
     int CustomerNumber {get;set;}
     List<Balance> Balances{get;set;}
}

public class Balance
{
     int CustomerNumber {get;set;}
     decimal Amount {get;set;}
}

所以让我们保存我有这个客户列表

List<Customer> customers = new List<Customer>{
new Customer {CustomerNumber = 1},
new Customer {CustomerNumber = 2},
new Customer {CustomerNumber = 3}
};

还有这个余额列表

List<Balance> balances = new List<Balance>{
new Balance {Amount = 10, CustomerNumber = 1},
new Balance {Amount = 20, CustomerNumber = 1},
new Balance {Amount = 30, CustomerNumber = 2},
new Balance {Amount = 80, CustomerNumber = 2},
new Balance {Amount = 100, CustomerNumber = 2},
new Balance {Amount = 50, CustomerNumber = 3},
};

最后我会有

  • 客户 1 将有一个包含 1020 金额的列表
  • 客户 2 将有一个包含 3080100 金额的列表
  • 客户 3 将有一个包含 50 数量的列表。

目前的解决方案如下:

foreach (var customer in customers)
{
    var matchingBalances = balances
                     .Where(x => x.CustomerNumber == customer.CustomerNumber);
    customer.Balances.AddRange(matchingBalances);
}

更新:这是我最终使用的。

var merge2 = customers.GroupJoin(balances,
        c => c.CustomerNumber,
        b => b.CustomerNumber,
        (c, b) =>
        {                
            c.Balances = b.ToList()
            return c;
        });

【问题讨论】:

  • 嗯,这听起来像一个连接 - 那么你有什么尝试 - 你期望结果是什么?
  • 我看到你评论了@KevinOwens 回答说你正在使用那个解决方案,在我看来这是处理这个问题的好方法。如果您希望优化现有功能,您应该将您已经在使用的功能以及您希望优化的具体方法、更快的处理速度、更低的内存占用等放在一起。
  • 感谢您的提示。我的下一篇文章会更好!
  • 我也在下面发布了GroupJoin 解决方案,这也可能有所帮助。
  • 在 LINQ 中产生副作用是不好的做法。

标签: c# linq list merge


【解决方案1】:

试试GroupJoin...

这将汇总金额...

var merge = customers.GroupJoin(balances, 
            c => c.CustomerNumber, 
            b => b.CustomerNumber,
            (c, b) => new
            {
                custname = c.CustomerNumber, 
                custamount = b.Sum(b2 => b2.Amount)
            });

            foreach (var cust in merge)
            {
                Console.WriteLine("{0}: {1}", cust.custname, cust.custamount);
            }

下面将列出它们......

        var merge2 = customers.GroupJoin(balances,
            c => c.CustomerNumber,
            b => b.CustomerNumber,
            (c, b) => new
            {
                custname = c.CustomerNumber,
                custamount = b.ToList()
            });

        foreach (var cust in merge2)
        {
            Console.WriteLine("Customer {0} has following amounts: ", 
                cust.custname);

            foreach (var amount in cust.custamount)
            {
                Console.WriteLine(amount.Amount);
            }
        }

图像显示输出。

【讨论】:

  • 我最终使用了这个和 Toons33 解决方案的组合。我会更新 OP。
  • @mmeyer 这基本上就是我在这里发布的内容?
【解决方案2】:

试试这个:

foreach (var customer in customers)
{
    var matchingBalances = balances.Where(x => x.CustomerNumber == customer.CustomerNumber);
    customer.Balances.AddRange(matchingBalances);
}

【讨论】:

  • 这是我目前正在做的事情,我正在寻找一种更有效的方法将两者联系起来。
【解决方案3】:
var combined = from c in customers
               join b in balance on b.CustomerNumber equal c.CustomerNumber
               select new{
                   Amount = b.Amount,
                   Balance = c.Balance,
                   };

【讨论】:

  • 你在正确的轨道上,但这不会产生预期的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 2018-05-12
  • 2019-04-30
  • 1970-01-01
  • 2013-06-07
  • 2019-01-16
相关资源
最近更新 更多