C#循环中Model数据添加异常:结果超限且字段值重复排查
问题分析与修复建议
问题现象
预期仅获取bnghitung>0的2条记录,但实际model.ReportBungaRealSBPDetails被赋值为equery的全部39条记录,且所有记录的bnghitung值完全相同。
代码片段
var subQuerytrue = from trd in _context.TrdSbphtms where trd.Sell == false && trd.TrdOhDp == request.KodeDp group trd by trd.TrdOhKode into g select new { TRD_OH_Kode = g.Key, SisaNominal = g.Sum(x => x.SisaNominal) }; var equery = (from a in subQuerytrue join mobl in _context.Mobls on a.TRD_OH_Kode equals mobl.MoblCode into moblGroup from m in moblGroup.DefaultIfEmpty() where m.MoblMaturityDate > td select new { PIHAK = m.MoblIssuer ?? "", NAMAINVESTASI = a.TRD_OH_Kode ?? "", TGLJATUHTEMPO = m.MoblMaturityDate, SUKUBUNGA = m.MoblInterest ?? 0, HARIDIAKUI = m.MoblJangka * 30, HARITAHUN = 360, JANGKA = m.MoblJangka ?? 0, TGLTERBIT = m.MoblIssuedDate, TGLBUNGA = m.MoblTanggalBunga ?? 0, SISANOMINAL = a.SisaNominal ?? 0, MOBLCODE = m.MoblCode ?? "" }).ToList(); if (equery.Any()) { foreach (var item in equery) { jangka = item.JANGKA; DateTime defaultDate = new(2000, 1, 1); DateTime? ptgljthtempo = item.TGLJATUHTEMPO; DateTime? ptglterbit = item.TGLTERBIT; int? ptglbunga = item.TGLBUNGA; double? psisanominal = item.SISANOMINAL; string? pnamainvestasi = item.NAMAINVESTASI; string? MOBLCODE = item.MOBLCODE; int monthsDifference = ((ptgljthtempo ?? defaultDate).Year - (ptglterbit ?? defaultDate).Year) * 12 + (ptgljthtempo ?? defaultDate).Month - (ptgljthtempo ?? defaultDate).Month; max_pay = monthsDifference / jangka; if (ptglterbit != null) { int monthsDiff = ((td.Year - ptglterbit.Value.Year) * 12) + td.Month - ptglterbit.Value.Month; if (monthsDifference % jangka == 0) { bayar_ke = monthsDiff / jangka; } else { bayar_ke = 0; } } if (bayar_ke > 0) { if (ptglbunga != null) { DateTime targetDate = new((request.Periode ?? defaultDate).Year, (request.Periode ?? defaultDate).Month, (int)ptglbunga); var rs3 = (from trd in _context.TrdSbphtmSells where trd.TglBeli > targetDate && trd.TrdOhKode == MOBLCODE select trd.Nominal).Sum(); bnghitung = jangka * (int)ptglbunga * ((psisanominal ?? 0) - (rs3 > 0 ? rs3.Value ?? 0 : 0)) / 1200; bng = 0; tglbunga = new DateTime((request.PeriodTo ?? defaultDate).Year, (request.PeriodTo ?? defaultDate).Month, (int)ptglbunga); Nom = 0; var rs3true = (from trd in _context.TrdSbphtms where trd.TglBeli > tglbunga && trd.TrdOhKode == pnamainvestasi group trd by 1 into g select new { a = g.Sum(x => x.SisaNominal), b = g.Sum(x => x.Nominal) }).FirstOrDefault(); Nom = rs3true?.a ?? 0; var rs4true = (from trd in _context.TrdSbphtmSells where trd.TglBeli > tglbunga && trd.TrdOhKode == pnamainvestasi group trd by 1 into g select new { a = g.Sum(x => x.SisaNominal), b = g.Sum(x => x.Nominal) }).FirstOrDefault(); Nom += rs4true?.a ?? 0; if (bnghitung > 0) { var detailquery = equery.Select(s => new { s.PIHAK, s.NAMAINVESTASI, TGLJATUHTEMPO = tglbunga, NILAINOMINAL = (psisanominal - Nom) == 0 ? rs4true?.b * -1 : psisanominal - Nom, s.SUKUBUNGA, s.HARIDIAKUI, s.HARITAHUN, BUNGAHITUNG = bnghitung, BUNGAREAL = bng, TANGGALTERIMA = tglbunga, Keterangan = bayar_ke + " dari " + max_pay }); // DETAIL model.ReportBungaRealSBPDetails = detailquery.Where(w => w.BUNGAHITUNG > 0).Select(s => new ReportBungaRealSBPDetail { PIHAK = s.PIHAK, NAMAINVESTASI = s.NAMAINVESTASI, TGLJATUHTEMPO = s.TGLJATUHTEMPO, NILAINOMINAL = s.NILAINOMINAL, SUKUBUNGA = s.SUKUBUNGA, HARIDIAKUI = s.HARIDIAKUI, HARITAHUN = s.HARITAHUN, BUNGAHITUNG = s.BUNGAHITUNG, BUNGAREAL = s.BUNGAREAL, TANGGALTERIMA = s.TANGGALTERIMA, Keterangan = s.Keterangan }).ToList(); } } } } }
问题根源
- 遍历全量集合而非当前项:在
if (bnghitung > 0)块中,使用equery.Select(...)遍历整个equery集合生成detailquery,而非基于当前循环的item创建单个记录,导致每次都会生成39条记录。 - 变量复用导致值一致:
bnghitung、tglbunga等变量是当前循环的临时值,用它给整个detailquery的所有记录赋值,会导致所有记录的bnghitung完全相同。 - 覆盖而非累加结果:每次循环赋值
model.ReportBungaRealSBPDetails时,都会直接覆盖之前的结果,而非将符合条件的记录追加到列表中。 - 月份差计算错误:原代码中
monthsDifference的计算逻辑存在笔误,导致差值始终为0,影响后续max_pay和bayar_ke的正确性。
修复方案
步骤1:初始化空列表
在foreach循环前初始化结果列表,避免覆盖原有数据:
if (equery.Any()) { model.ReportBungaRealSBPDetails = new List<ReportBungaRealSBPDetail>(); foreach (var item in equery) { // 原有循环逻辑... } }
步骤2:修正月份差计算逻辑
修复monthsDifference的计算笔误:
// 修正前(错误) // int monthsDifference = ((ptgljthtempo ?? defaultDate).Year - (ptglterbit ?? defaultDate).Year) * 12 + (ptgljthtempo ?? defaultDate).Month - (ptgljthtempo ?? defaultDate).Month; // 修正后 int monthsDifference = ((ptgljthtempo ?? defaultDate).Year - (ptglterbit ?? defaultDate).Year) * 12 + (ptgljthtempo ?? defaultDate).Month - (ptglterbit ?? defaultDate).Month;
步骤3:基于当前item生成单个记录并追加
在if (bnghitung > 0)块中,直接基于当前item构造符合条件的记录,追加到结果列表:
if (bnghitung > 0) { var detailItem = new ReportBungaRealSBPDetail { PIHAK = item.PIHAK, NAMAINVESTASI = item.NAMAINVESTASI, TGLJATUHTEMPO = tglbunga, NILAINOMINAL = (psisanominal - Nom) == 0 ? rs4true?.b * -1 : psisanominal - Nom, SUKUBUNGA = item.SUKUBUNGA, HARIDIAKUI = item.HARIDIAKUI, HARITAHUN = item.HARITAHUN, BUNGAHITUNG = bnghitung, BUNGAREAL = bng, TANGGALTERIMA = tglbunga, Keterangan = $"{bayar_ke} dari {max_pay}" }; model.ReportBungaRealSBPDetails.Add(detailItem); }
修复后关键代码片段
if (equery.Any()) { model.ReportBungaRealSBPDetails = new List<ReportBungaRealSBPDetail>(); foreach (var item in equery) { jangka = item.JANGKA; DateTime defaultDate = new(2000, 1, 1); DateTime? ptgljthtempo = item.TGLJATUHTEMPO; DateTime? ptglterbit = item.TGLTERBIT; int? ptglbunga = item.TGLBUNGA; double? psisanominal = item.SISANOMINAL; string? pnamainvestasi = item.NAMAINVESTASI; string? MOBLCODE = item.MOBLCODE; // 修正后的月份差计算 int monthsDifference = ((ptgljthtempo ?? defaultDate).Year - (ptglterbit ?? defaultDate).Year) * 12 + (ptgljthtempo ?? defaultDate).Month - (ptglterbit ?? defaultDate).Month; max_pay = monthsDifference / jangka; if (ptglterbit != null) { int monthsDiff = ((td.Year - ptglterbit.Value.Year) * 12) + td.Month - ptglterbit.Value.Month; if (monthsDifference % jangka == 0) { bayar_ke = monthsDiff / jangka; } else { bayar_ke = 0; } } if (bayar_ke > 0) { if (ptglbunga != null) { DateTime targetDate = new((request.Periode ?? defaultDate).Year, (request.Periode ?? defaultDate).Month, (int)ptglbunga); var rs3 = (from trd in _context.TrdSbphtmSells where trd.TglBeli > targetDate && trd.TrdOhKode == MOBLCODE select trd.Nominal).Sum(); bnghitung = jangka * (int)ptglbunga * ((psisanominal ?? 0) - (rs3 > 0 ? rs3.Value ?? 0 : 0)) / 1200; bng = 0; tglbunga = new DateTime((request.PeriodTo ?? defaultDate).Year, (request.PeriodTo ?? defaultDate).Month, (int)ptglbunga); Nom = 0; var rs3true = (from trd in _context.TrdSbphtms where trd.TglBeli > tglbunga && trd.TrdOhKode == pnamainvestasi group trd by 1 into g select new { a = g.Sum(x => x.SisaNominal), b = g.Sum(x => x.Nominal) }).FirstOrDefault(); Nom = rs3true?.a ?? 0; var rs4true = (from trd in _context.TrdSbphtmSells where trd.TglBeli > tglbunga && trd.TrdOhKode == pnamainvestasi group trd by 1 into g select new { a = g.Sum(x => x.SisaNominal), b = g.Sum(x => x.Nominal) }).FirstOrDefault(); Nom += rs4true?.a ?? 0; if (bnghitung > 0) { var detailItem = new ReportBungaRealSBPDetail { PIHAK = item.PIHAK, NAMAINVESTASI = item.NAMAINVESTASI, TGLJATUHTEMPO = tglbunga, NILAINOMINAL = (psisanominal - Nom) == 0 ? rs4true?.b * -1 : psisanominal - Nom, SUKUBUNGA = item.SUKUBUNGA, HARIDIAKUI = item.HARIDIAKUI, HARITAHUN = item.HARITAHUN, BUNGAHITUNG = bnghitung, BUNGAREAL = bng, TANGGALTERIMA = tglbunga, Keterangan = $"{bayar_ke} dari {max_pay}" }; model.ReportBungaRealSBPDetails.Add(detailItem); } } } } }
内容的提问来源于stack exchange,提问作者Haminteu
相关产品推荐
相关产品推荐

