Entity Framework Core: как выполнить объединение в `IQueryable`, выбрав только последние созданные записи? - PullRequest
0 голосов
/ 01 июля 2019

Я выполняю рефакторинг кода, который создает дубликаты:

private IQueryable<CashoutModel> GetCashoutModels() =>
    from cashout in _context.Cashouts
    join audit in _context.Audits
        on cashout.Id.ToString() equals audit.EntityId
        into cashoutModel
    from audit in cashoutModel.DefaultIfEmpty()
    orderby cashout.CreatedOn descending
    select new CashoutModel
    {
        Id = cashout.Id,
        Amount = cashout.Amount,
        Comment = cashout.Comment,
        CreatedOn = cashout.CreatedOn,
        RecipientAccountId = cashout.RecipientAccountId,
        RecipientAccountName = cashout.RecipientAccountName,
        State = cashout.State,
        Reason = cashout.Reason,
        CreatedBy = audit == null 
            ? null 
            : audit.Name
    };

_context.Audits фактически записывает (инициируемые использованием) изменения, которые происходят для определенных записей в _context.Cashout.

Я ищу простой способ исправить текущее поведение join, выбрав только (для данного EntityId) самую последнюю запись аудита.

1 Ответ

1 голос
/ 02 июля 2019

Код, который у вас есть в настоящее время, по существу делает LEFT OUTER JOIN, который получает все записи о выплатах и ​​соответствующую запись аудита.

Предполагая, что у вас есть столбец отметки времени (скажем, CreatedOn ) в таблице Audits, которая фиксирует момент создания этой записи аудита, вы можете использовать GROUP JOIN вот так вот -

private IQueryable<CashoutModel> GetCashoutModels() =>
_context.Cashouts.GroupJoin(_context.Audits,
                            c => c.Id.ToString(),
                            a => a.EntityId,
                            (cashout, audit) => new CashoutModel
                                {
                                    Id = cashout.Id,
                                    Amount = cashout.Amount,
                                    Comment = cashout.Comment,
                                    CreatedOn = cashout.CreatedOn,
                                    RecipientAccountId = cashout.RecipientAccountId,
                                    RecipientAccountName = cashout.RecipientAccountName,
                                    State = cashout.State,
                                    Reason = cashout.Reason,
                                    CreatedBy = audit.OrderByDescending(x => x.CreatedOn)
                                                    .Select(y => y.Name)
                                                    .FirstOrDefault()
                                }).AsQueryable();
...