From 1d9bac4dd61e41a7bd2321c2ecc98537a9b268f0 Mon Sep 17 00:00:00 2001 From: hjhan <18049703642@163.com> Date: Sat, 15 Aug 2026 13:44:53 +0800 Subject: [PATCH] =?UTF-8?q?refactor(swap):=20=E6=8F=90=E5=8F=96=20EodSwapP?= =?UTF-8?q?ositionQueries.ActiveByTradeAndDate=20=E6=94=B6=E5=8F=A3?= =?UTF-8?q?=E6=97=A5=E7=BB=88=E6=9C=89=E6=95=88=E6=8C=81=E4=BB=93=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 eod_swap_position 上'SwapTradeId + ValueDate + !Invalid'的 5 处重复谓词 (SwapEodPositionService.cs:2133/2195/2246/2487、ConfirmationGenerateContext.cs:2868) 收口到 EodSwapPositionQueries.ActiveByTradeAndDate(tradeId, valueDate), 与 SwapPositionQueries.ActiveByTrade 同构,零逻辑变更。 --- .../SwapModule/EodSwapPositionQueries.cs | 19 +++++++++++++++++++ .../SwapModule/SwapEodPositionService.cs | 8 ++++---- .../ConfirmationGenerateContext.cs | 3 ++- 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 YLErpDAL/Modules/SwapModule/EodSwapPositionQueries.cs diff --git a/YLErpDAL/Modules/SwapModule/EodSwapPositionQueries.cs b/YLErpDAL/Modules/SwapModule/EodSwapPositionQueries.cs new file mode 100644 index 00000000..7041def4 --- /dev/null +++ b/YLErpDAL/Modules/SwapModule/EodSwapPositionQueries.cs @@ -0,0 +1,19 @@ +using System; +using System.Linq; +using YLErp.DBModels; + +namespace YLErp.Modules.SwapModule +{ + /// + /// eod_swap_position 查询收口(Query Object)。 + /// 规则"某交易某日日终的有效持仓 = SwapTradeId 匹配 + ValueDate 匹配 + 未作废(!Invalid)"集中于此, + /// 避免多处复制同一谓词导致语义漂移(漏写 !Invalid 即静默出 bug)。 + /// 仅返回 IQueryable,不调用 SaveChanges,不破坏跟踪/Include/事务边界。 + /// + public static class EodSwapPositionQueries + { + public static IQueryable ActiveByTradeAndDate( + this IQueryable query, int tradeId, DateTime valueDate) + => query.Where(x => x.SwapTradeId == tradeId && x.ValueDate == valueDate && !x.Invalid); + } +} diff --git a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs index 1faad620..d6fa2a48 100644 --- a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs @@ -2130,7 +2130,7 @@ namespace YLErp.Modules.SwapModule var tradeSpan = DbContext.trade_span.FirstOrDefault(x => x.TradeId == td.id && x.ValueDate == settleDate); // eod_swap 是交易级汇总;eod_swap_position 是浮动腿、利息腿和保证金腿的明细。 // 以下先按日终明细拆腿,再按框架合约展示口径汇总。 - var eodSwapPositions = DbContext.eod_swap_position.Where(x => x.SwapTradeId == td.id && x.ValueDate == settleDate && !x.Invalid).ToList(); + var eodSwapPositions = DbContext.eod_swap_position.ActiveByTradeAndDate(td.id, settleDate).ToList(); var interestPositions = eodSwapPositions.Where(x => string.IsNullOrEmpty(x.UnderlyingCode)).ToList();//利息腿 var positions = eodSwapPositions.Where(x => !string.IsNullOrEmpty(x.UnderlyingCode)).ToList();//持仓腿 // 框架合约的方向约定:多头为正、空头为负;总名义本金取交易原始规模, @@ -2192,7 +2192,7 @@ namespace YLErp.Modules.SwapModule DbContext.eod_swap.Add(eod_Swap); } // 单标的调整与首次归档使用同一套框架合约汇总口径,避免重算后多空和名义本金展示不一致。 - var eodSwapPositions = DbContext.eod_swap_position.Where(x => x.SwapTradeId == td.id && x.ValueDate == settleDate && !x.Invalid).ToList(); + var eodSwapPositions = DbContext.eod_swap_position.ActiveByTradeAndDate(td.id, settleDate).ToList(); var interestPositions = eodSwapPositions.Where(x => string.IsNullOrEmpty(x.UnderlyingCode)).ToList();//利息腿 var positions = eodSwapPositions.Where(x => !string.IsNullOrEmpty(x.UnderlyingCode)).ToList();//持仓腿 eod_Swap.NotionalValue = Math.Round(Convert.ToDecimal(td.OriginalStockEqvNotional ?? td.StockEqvNotional), ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero); @@ -2243,7 +2243,7 @@ namespace YLErp.Modules.SwapModule public SwapLongShortCloseModel GetCloseDetails(int tradeId, DateTime valueDate) { SwapLongShortCloseModel closeModel = new SwapLongShortCloseModel(); - var eodPositions = DbContext.eod_swap_position.Where(x => x.SwapTradeId == tradeId && x.ValueDate == valueDate && !x.Invalid).ToList(); + var eodPositions = DbContext.eod_swap_position.ActiveByTradeAndDate(tradeId, valueDate).ToList(); var flowEvents = DbContext.swap_flow_event.Where(x => x.SwapTradeId == tradeId && x.EventDate == valueDate && x.DataState == (int)SwapFlowDateStateEnum.完成 && x.EventType == (int)SwapEventTypeEnum.平仓 && string.IsNullOrEmpty(x.UnderlyingCode)).ToList(); closeModel.DealPositions = eodPositions.Where(x => x.TdCloseQty != 0).ToList(); closeModel.DealInterests = flowEvents; @@ -2484,7 +2484,7 @@ namespace YLErp.Modules.SwapModule /// public List GetPreEodPositions(int tradeId, DateTime valueDate) { - return DbContext.eod_swap_position.Where(x => x.SwapTradeId == tradeId && x.ValueDate == valueDate && !x.Invalid).ToList(); + return DbContext.eod_swap_position.ActiveByTradeAndDate(tradeId, valueDate).ToList(); } /// /// 获取互换交易日终持仓数据集合 diff --git a/YLErpDAL/Modules/TradeModule/DocGenerateModule/ConfirmationGenerateContext.cs b/YLErpDAL/Modules/TradeModule/DocGenerateModule/ConfirmationGenerateContext.cs index 2ac4c1ac..319889ac 100644 --- a/YLErpDAL/Modules/TradeModule/DocGenerateModule/ConfirmationGenerateContext.cs +++ b/YLErpDAL/Modules/TradeModule/DocGenerateModule/ConfirmationGenerateContext.cs @@ -34,6 +34,7 @@ using YLErp.Office.Converters; using YLErp.Plugins.TradeDocGenerator; using YLErp.Plugins.TradeDocGenerator.Abstracts; using YLErp.QdpModule; +using YLErp.Modules.SwapModule; namespace YLErp.Modules.TradeModule.DocGenerateModule { @@ -2864,7 +2865,7 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule } public List GetEodPositions(int tradeId, DateTime valueDate) { - return DbContext.eod_swap_position.Where(x => x.SwapTradeId == tradeId && !x.Invalid && x.ValueDate == valueDate).AsNoTracking().ToList(); + return DbContext.eod_swap_position.ActiveByTradeAndDate(tradeId, valueDate).AsNoTracking().ToList(); } public List GetSwapFlowDeals(int tradeId)