You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在新增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ç

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 11:06:02