public bool IsPayback(long debtDealId) { DebtDealAnalysisRow ar = this.rdbc.DebtDealsAnalysis .Where(dda => dda.DebtDealId == debtDealId) .First(); return(ar.IsPayback); }
public long Add(DebtDealRow deal) { /* * *** Notes on parallel execution *** * * If two debt deals have 4 unique involved people id-s, * these same deals may be processed in parallel in this register * (but may need serialization while other registers handle * DebtDealAdded event). * * Need to consider validity of initialGiverDebtToTaker. * * Other cases: * three unique involved id-s: * same giver, different takers: => parallel-ok * * different givers, same taker: => parallel-ok * * two unique involved id-s: * same giver, same taker => serialize (case a) * * D1.giver = D2.taker, D1.taker = D2.giver * => serialize (case b) * * * Here, parallel execution has to be serialized when register * has not finished processing two deals which match one of these: * a) if giver and taker are the same for two deals, * later deal must wait till earlier one is fully processed. * (consider small and complete pay-back immediately * followed by a big credit - if D1 is processed after D2 * was fully processed, big credit could be considered * as mostly a GIFT, confusing it with a payback) * * b) if D1.giver = D2.taker, D1.taker = D2.giver * (consider pay and repay of the same amount - * in case of parallel execution of both deals, * payback could be missed and DB would get corrupt) */ long addedDebtDealId; using (var transaction = this.dbc.Database.BeginTransaction()) { this.dbc.DebtDeals.Add(deal); this.dbc.SaveChanges(); // need deal.Id addedDebtDealId = deal.Id; decimal initialGiverDebtToTaker = GiverDebtToTaker(); decimal?repayGiftAmount = null; if (initialGiverDebtToTaker > 0m) { repayGiftAmount = Math.Max(0m, deal.Amount - initialGiverDebtToTaker); } var analysisRow = new DebtDealAnalysisRow() { DebtDealId = deal.Id, IsPayback = initialGiverDebtToTaker > 0m }; this.dbc.DebtDealsAnalysis.Add(analysisRow); this.dbc.SaveChanges(); DebtDealReceived?.Invoke(this, new DebtDealReceivedEventData() { Deal = deal, Analysis = analysisRow, RepayGiftAmount = repayGiftAmount }); transaction.Commit(); } DebtDealAdded?.Invoke(this, new DebtDealAddedEventData() { AddedDebtDealId = addedDebtDealId }); return(addedDebtDealId); decimal GiverDebtToTaker() { return(this.dbc.CurrentDebts.Where(cd => cd.CreditorId == deal.TakerId && cd.DebtorId == deal.GiverId ).Select(cd => cd.DebtTotal).FirstOrDefault()); } }