I am refactoring a code in production which create duplicates:
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
};
The _context.Audits
actually records (use-triggered) changes that happen for certain records in _context.Cashout
.
I am looking for a clean way to fix the current behavior of the join
by selecting only (for a given EntityId
) the latest audit record.
The code you currently have is essentially doing a LEFT OUTER JOIN
which gets all the Cashouts records and the corresponding audit record.
Assuming you have a timestamp column (say CreatedOn ) in the Audits
table which captures when that audit record was created, you could use a GROUP JOIN here like so -
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();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.