C# 结合 Entity Framework 使用 LINQ 多表查询入库的优化方案咨询
优化实现方案
问题根源
- 原有代码中错误直接从FRA实体读取属于FRSA表的
ScopingSrc、Mandatory字段,本身就无法获取到正确值 - 原有两层循环会触发N+1次数据库查询,FRSA查询次数等于FRA筛选后的记录数,性能极低,同时EF循环中的变量捕获机制容易导致取值错乱
- 原有代码错误将单个实体传入
AddRange方法,该方法仅支持传入集合类参数 - 两层循环的局部变量作用域限制,无法跨循环正常传递值
优化后代码实现
1. 一次性关联查询两张表
使用Linq Join一次性关联Fra和Frsa表,加载所有需要的字段,避免循环查询数据库:
// 关联查询两张表,按需取字段,1对多场景下可去掉Distinct保留所有FRSA匹配记录 var mergeData = (from fra in _cctDBContext.Fra where fra.ActTypeId == 1 join frsa in _cctDBContext.Frsa on fra.Fraid equals frsa.Fraid select new { fra.Fraid, fra.Fra1, frsa.ScopingSrc, frsa.Mandatory // 其他需要的字段可在此处补充 }).Distinct().ToList();
2. 批量构造实体并入库
一次性构造所有目标实体,批量添加到上下文后统一提交:
// 批量构造目标实体集合 var reportingActivities = mergeData.Select(item => new FinancialReportingActivity { FinancialReportingActivityId = item.Fraid, ScopingSourceType = item.ScopingSrc, Name = item.Fra1, MandatoryIndicator = item.Mandatory, WorkEffortTypeId = 0 }).ToList(); // 批量添加到上下文 _clDBContext.FinancialReportingActivity.AddRange(reportingActivities); // 统一提交保存 _clDBContext.SaveChanges();
额外说明
如果Fra和Frsa是1对多关系,需要为每一条FRSA记录生成对应入库数据,直接去掉关联查询中的Distinct()即可,关联结果会保留所有匹配的FRSA记录。
内容的提问来源于stack exchange,提问作者Jason_Hough
相关产品推荐
相关产品推荐

