使用EFCore.BulkExtensions能否基于关联表判断批量增改?
问题场景
需要用EFCore.BulkExtensions实现BulkInsertOrUpdate,但判断插入/更新的依据不是Product.Id,而是指定供应商的Sku(即{SupplierId, Sku}组合)。由于Product实体没有直接存储供应商信息,需通过ProductSupplier关联表关联供应商;同时要解决插入新Product时自动创建对应的ProductSupplier记录的问题,也曾考虑过使用LinqToDB。
现有代码示例
关联查询示例
var currentProducts = (from p in context.Products join ps in context.ProductSuppliers on p.Id equals ps.ProductId into ppsJoin from pps in ppsJoin where pps.SupplierId == supplierId select new Product());
尝试的BulkConfig配置
var bulkConfig = new BulkConfig { PropertiesToIncludeOnCompare = new List<string> { nameof(Product.Sku) }, IncludeGraph = true };
目标调用
await context.BulkInsertOrUpdateAsync(productsToLoad, bulkConfig);
Product实体关联定义
public virtual ICollection<ProductSupplier> ProductSuppliers { get; set; } = new List<ProductSupplier>();
解决方案
由于EFCore.BulkExtensions无法直接基于跨表的组合条件(SupplierId+Sku)判断插入/更新,需要先通过预查询完成数据匹配,再结合批量配置实现需求:
- 预查询构建供应商-产品映射字典
先从数据库获取指定供应商下所有Product的Sku与Id的对应关系,用于后续匹配传入的待处理数据:
var supplierProductMap = context.ProductSuppliers .Where(ps => ps.SupplierId == supplierId) .Join(context.Products, ps => ps.ProductId, p => p.Id, (ps, p) => new { p.Sku, p.Id }) .ToDictionary(x => x.Sku, x => x.Id);
- 处理待批量操作的产品数据
遍历待处理的productsToLoad,区分更新与插入数据,并为新增产品绑定ProductSupplier:
foreach (var product in productsToLoad) { if (supplierProductMap.TryGetValue(product.Sku, out var existingProductId)) { // 匹配到现有产品,设置Id标记为更新 product.Id = existingProductId; } else { // 新增产品,创建对应的ProductSupplier关联记录 product.ProductSuppliers.Add(new ProductSupplier { SupplierId = supplierId // 无需手动设置ProductId,EF Core会自动维护 }); } }
- 配置并执行批量操作
调整BulkConfig,利用IncludeGraph自动插入关联的ProductSupplier,同时依赖Product.Id作为默认的更新判断依据(已通过映射字典完成匹配):
var bulkConfig = new BulkConfig { IncludeGraph = true, // 自动处理关联实体的插入 // 无需配置PropertiesToIncludeOnCompare,因为已通过Id匹配更新 }; await context.BulkInsertOrUpdateAsync(productsToLoad, bulkConfig);
关于LinqToDB的替代方案
如果使用LinqToDB,核心思路一致:先通过关联查询获取供应商与产品的映射,处理待操作数据后,使用BulkCopy结合自定义逻辑实现插入/更新,同样需要手动维护ProductSupplier的关联关系。
内容的提问来源于stack exchange,提问作者tonyatl
相关产品推荐
相关产品推荐

