Почему я получаю дубликаты ключей при использовании группового LINQ - PullRequest
0 голосов
/ 20 апреля 2020

Я использую следующий фрагмент, чтобы поймать все долги, принадлежащие клиенту, принадлежащему уникальному номеру счета. Однако я получаю дубликаты номеров счетов, даже если выбрал его в качестве ключа. Я слишком удивлен.

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

1 Ответ

0 голосов
/ 21 апреля 2020

Очевидно, вы ожидаете, что ваши AccountNumbers будут содержать символы, которые не являются цифрами, и вы не хотите их учитывать. Вы хотите, чтобы AccountNumbers содержали только цифры.

Чтобы запретить удаление цифр более одного раза за AccountNumber, мой совет - использовать для этого дополнительный выбор.

После удаления не-символов рассмотрите возможность преобразования 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 был нулевым, то groupedList является пустой последовательностью.

...