如何在新增Offer实体时同步添加多条关联的OfferDetail明细数据
第一步:调整入参OfferInfo类
在现有OfferInfo中新增明细集合属性,用于接收传入的多条报价明细数据:
public class OfferInfo { // 原有Offer相关属性保持不变 // 新增明细集合属性 public List<OfferDetailInfo> OfferDetails { get; set; } = new List<OfferDetailInfo>(); } // 新增明细对应的DTO类,属性和OfferDetail实体对应即可 public class OfferDetailInfo { public int RowNumber { get; set; } public int Quantity { get; set; } public string Description { get; set; } public decimal UnitPrice { get; set; } public decimal TotalPrice { get; set; } public string Definition { get; set; } public Boolean Optional { get; set; } public decimal UnitProfit { get; set; } public decimal UnitCost { get; set; } }
第二步:优化Offer实体类导航属性初始化
避免后续赋值时出现空引用异常:
public class Offer { public Offer() { // 初始化明细导航集合 OfferDetail = new List<OfferDetail>(); } // 剩余原有属性保持不变 }
第三步:修改AddOffer方法逻辑
EF Core支持级联插入,只要将明细实体关联到Offer的导航属性,一次提交即可同时插入主表和所有子表数据,自动维护主外键关系,还自带事务保障一致性:
public async Task<Result> AddOffer(OfferInfo offerInfo) { try { var vOffer = new Offer { Id = offerInfo.Id, CompanyId = offerInfo.CompanyId, CompanyContactId = offerInfo.CompanyContactId, OfferNumber = offerInfo.OfferNumber, Annotations = offerInfo.Annotations, CommercialConditions = offerInfo.CommercialConditions, TimeInformation = offerInfo.TimeInformation, ProfitRate = offerInfo.ProfitRate, Date = offerInfo.Date, ValidityDate = offerInfo.ValidityDate, }; // 转换明细DTO为实体,加入Offer的导航集合 foreach (var detailDto in offerInfo.OfferDetails) { var vDetail = new OfferDetail { RowNumber = detailDto.RowNumber, Quantity = detailDto.Quantity, Description = detailDto.Description, UnitPrice = detailDto.UnitPrice, TotalPrice = detailDto.TotalPrice, Definition = detailDto.Definition, Optional = detailDto.Optional, UnitProfit = detailDto.UnitProfit, UnitCost = detailDto.UnitCost }; vOffer.OfferDetail.Add(vDetail); } _context.Offers.Add(vOffer); // 一次提交即可完成主表+所有明细的插入,EF会自动填充OfferDetail的OfferId外键 await _context.SaveChangesAsync(); return Result.PrepareSuccess(); } catch (Exception vEx) { return Result.PrepareFailure(vEx.Message); } }
可选优化项
- 建议将Offer实体的导航属性
List<OfferDetail> OfferDetail改名为List<OfferDetail> OfferDetails,符合复数命名规范,可读性更高 - 如果
Offer.Id是数据库自增主键,不需要手动赋值,EF会自动获取生成的主键值 - 可在DbContext的
OnModelCreating方法中显式配置主外键关系,避免约定失效:
modelBuilder.Entity<OfferDetail>() .HasOne(d => d.Offer) .WithMany(o => o.OfferDetail) .HasForeignKey(d => d.OfferId) .OnDelete(DeleteBehavior.Cascade); // 不需要级联删除可修改为其他行为
内容的提问来源于stack exchange,提问作者Mert Tunç
相关产品推荐
相关产品推荐

