首页 > 解决方案 > 为什么我在使用 groupby LINQ 时会得到重复的键

问题描述

我正在使用以下代码段来捕获属于客户的所有债务,这些债务属于唯一的帐号。但是,即使我选择它作为密钥,我也会得到重复的帐号。我太惊讶了。

var records      = myList;
var groupedList  = records?
                      .GroupBy(x => x.AccountNumber.Where(char.IsDigit).ToArray())
                      .Select(e => new {
                             AccountNumber = new string(e.Key), 
                             TotalDebt = e.Sum(x => x.TotalDebt)
                            }
                       );

q

标签: c#linqgroup-byigrouping

解决方案


显然,您希望您的 AccountNumbers 包含非数字字符,并且您不想考虑它们。您需要仅包含数字的 AccountNumbers。

为了防止每个 AccountNumber 多次删除数字,我的建议是为此使用额外的 Select。

删除非字符后,考虑将 AccountNumber 转换为 int,这将大大加快您的处理速度。如果您不想将其转换为 int,请删除 Parse 部分。

对此的另一个建议:永远不要让您的 LINQ 语句返回 NULL。您的 LINQ 语句的结果(只要它返回IEnumerable<...>)表示一系列相似项。如果序列中没有项目,则返回一个空序列。这样做的好处是您不必检查输入是否为空。

List<MyRecord> myList = ...
var records = myList ?? Enumerable.Empty<MyRecord>();
ver groupedList  = records.Select(record => new
{
    // Remove the non-digits, and parse to Int32 or Int64
    // I'm certain that this parses, because it is digits only (or out-of-range?)
    AccountNumber = Int32.Parse(record.AccountNumber.Where(c => Char.IsDigit(c))),

    Debt = record.TotalDebt,  // are you sure this property is also called TotalDebt?
})

// Now the GroupBy is easy and efficient:
.GroupBy(record => record.AccountNumber,
(accountNumber, recordsWithThisAccountNumber) => new
{
    AccountNumber = accountNumber,
    TotalDebt = recordsWithThisAccountNumber.Sum()
});

现在您可以确定 groupedList 是一个非空序列。如果 myList 为 null,则 groupedList 为空序列。


推荐阅读