Добавьте дополнительное значение из LINQ - PullRequest
0 голосов
/ 14 марта 2019

У меня есть следующий бит кода:

var checkRegisters = await Database.Client.Context.CheckRegister
            .Where(cr => cr.CheckingAccount == account 
                   && cr.CheckDate >= fromDate 
                   && cr.CheckDate <= toDate 
                   && cr.Void == "N" )
            .GroupBy(cr => cr.CheckNumber, 
                     cr => cr.Amount, (key, g) => 
                                          new { 
                                                CheckNumber = key, 
                                                Amount = g.Sum()
                                              })
            .OrderBy(c => c.CheckNumber)
            .ToListAsync();

Я не до конца понимаю, что он делает, кроме того, что возвращает мне список CheckNumber и Amount. В таблице CheckRegister содержится столбец Payee, а также соответствующий modelBuilder из EF:

entity.Property(e => e.Payee).HasColumnType("varchar(255)");

Как я могу добавить получателя в список, в который я вернулась?

Ответы [ 3 ]

2 голосов
/ 14 марта 2019

Что делает код:

В вашей базе данных есть таблица, содержащая CheckRegisters. Каждый CheckRegister имеет как минимум свойства CheckingAccount, CheckDate, Void, CheckNumber и Amount, и, по вашему мнению, он также имеет свойство Payee:

Итак, ваш код описан шаг за шагом.

// Take the complete table of CheckRegisters:
Database.Client.Context.CheckRegister

// from every checkRegister in this table (every row),
// keep only those checkRegisters that have a CheckingAccount value equal to account
// and a CheckDate value betwen fromData and toDate
// and a value for property Void equalt to "N"

.Where(checkRegister => checkRegister.CheckingAccount == account 
                     && checkRegister.CheckDate >= fromDate 
                     && checkRegister.CheckDate <= toDate 
                     && checkRegister.Void == "N" )

// Group all remaining CheckRegisters into groups with same checkNumber
// Each group will have a property Key which has the value of the common CheckNumber
        .GroupBy(cr => cr.CheckNumber,

           // ElementSelector: from every CheckRegister put only the amount in each grouop 
           checkRegister => checkRegister.Amount,

           // ResultSelector: take every key (which we call checkNumber)
           // and all Amounts of all CheckRegisters with this CheckNumber
           // to make one new object:
           (checkNumber, amountsFromCheckRegistersWithThisCheckNumber) => new
           { 
                CheckNumber = key, 

                // To calculate property Amount: sum all amountsFromCheckRegistersWithThisCheckNumber
                Amount = amountsFromCheckRegistersWithThisCheckNumber.Sum(),
           })

// By now you have a sequence of objects, each with two properties:
// CheckNumber: a checkNumber used in the CheckRegisters that were left after the Where
// Amount: the sum of all Amounts of all CheckRegisters that have this CheckNumber

// Finally you do some Ordering, and convert the resulting elements into a list
.OrderBy(groupedItem => groupedItem.CheckNumber)
.ToListAsync();

Теперь желаемое изменение: Добавьте Payees.

Проблема в том, что возвращаемые данные - это CheckRegisters, сгруппированные по CheckNumber. Каждый получатель платежа за каждого чекового регистра. Если вы создаете группы CheckRegisters с одним и тем же CheckNumber, вы получаете несколько получателей с этим CheckNumber:

CheckNumber | Payee | ...
    1       |   A
    2       |   B
    1       |   C
    2       |   C    // note: C  is used again
    1       |   D

Если я создаю группы с одинаковым CheckNumber, вы получите:

group CheckNumber 1 [1, A], [1,C], [1,D]
group CheckNumber 2 [2, B], [2,C]

Таким образом, в каждой группе может быть более одного сотрудника. Если с вами все в порядке, просто опустите ElementSelector и выберите «Сотрудники» в ResultSelector

var result = Database.Client.Context.CheckRegister
.Where(...)
.GroupBy(cr => cr.CheckNumber,

// ResultSelector: take every key (which we call checkNumber)
// and all CheckRegisters with this CheckNumber
// to make one new object:
(checkNumber, checkRegistersWithThisCheckNumber) => new
{ 
    CheckNumber = checkNumber, 

    // for Employees: Select property Employee, and convert them to a List
    Employees = checkRegistersWithThisCheckNumber
                .Select(checkRegister => checkRegister.Employee)
                .ToList(),

    // Amounts: select the Amounts and Sum
    Amount = checkRegistersWithThisCheckNumber
                 .Select(checkRegister => checkRegister.Amount)
                 .Sum(),
    });
1 голос
/ 14 марта 2019

Я бы добавил его к объекту, который вы создаете в GroupBy. Поэтому измените строку 3, как показано ниже

.GroupBy(cr => cr.CheckNumber, cr => cr.Amount, cr => cr.Payee, (key, g) => 
                              new { CheckNumber = key, Amount = g.Sum(), Payee = g.Payee})

Обратите внимание, что группировка по была разделена только по номеру и сумме, поэтому, если вы также группируете по получателю, следует ожидать, что итоговый список будет длиннее. Это также предполагает, что Получатель - это имя столбца в вашей таблице.

0 голосов
/ 14 марта 2019

Добавить новый столбец в группу:

var checkRegisters = await Database.Client.Context.CheckRegister
            .Where(cr => cr.CheckingAccount == account && cr.CheckDate >= fromDate && cr.CheckDate <= toDate && cr.Void == "N" )
            .GroupBy(cr => cr.CheckNumber, cr => cr.Amount, e => e.Payee , (key, g, p) => new { CheckNumber = key, Amount = g.Sum(), Payee = p})
            .OrderBy(c => c.CheckNumber).ToListAsync();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...