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

保存Order后添加Order item触发FOREIGN KEY约束冲突问题求助

问题描述

先向数据库添加主表Order(对应实体Narudzba),再添加Order Item(对应实体Stavka_narudzbe),预期Order Item在Order保存后写入对应的OrderID。Order已成功保存,但Order Item无法立即识别到该Order,抛出如下错误:

SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint

尝试了异步和同步两种方式都无效,相关代码如下:

业务层代码

// 保存Order
Narudzba narudzba = new Narudzba
{
    datum_vrijeme = selectedDateTime.Value,
    racun = GenerateRacun(),
    status = "Zaprimljeno",
    Korisnik_id_korisnik = korisnik.id_korisnik
};

await _narudzbaServices.AddNarudzbuAsync(narudzba);

// 保存Order items
foreach (var jelo in _selectedFoodItems)
{
    Stavka_narudzbe stavka_Narudzbe = new Stavka_narudzbe
    {
        kolicina = "1",
        prilagodbe = null,
        Narudzba_id_narudzba = narudzba.id_narudzba,
        Jelo_id_jelo = jelo.id_jelo,
        Pice_id_pice = null
    };
    _stavka_narudzbeServices.AddStavkeNarudzbe(stavka_Narudzbe);
}

仓储层添加Order的实现

public override Task<int> AddAsync(Narudzba entity, bool saveChanges = true)
{
    var narudzba = new Narudzba
    {
        datum_vrijeme = entity.datum_vrijeme,
        racun = entity.racun,
        status = entity.status,
        Korisnik_id_korisnik = entity.Korisnik_id_korisnik
    };

    Entities.Add(narudzba);

    if (saveChanges)
    {
        return Task.FromResult(SaveChanges());
    }
    else
    {
        return Task.FromResult(0);
    }
}
解决方案

问题核心:仓储层的AddAsync方法新建了一个Narudzba对象,而非直接使用传入的entity参数。当调用SaveChanges()后,EF会为新建的对象生成ID,但这个ID不会回传给业务层的narudzba变量,导致后续创建Stavka_narudzbe时使用的narudzba.id_narudzba是初始值(如0或null),触发外键约束冲突。

修复步骤:

  1. 修改仓储层的AddAsync方法,直接使用传入的实体对象,避免重新实例化:
public override Task<int> AddAsync(Narudzba entity, bool saveChanges = true)
{
    Entities.Add(entity); // 直接添加传入的实体,SaveChanges后EF会自动填充entity的ID

    if (saveChanges)
    {
        return Task.FromResult(SaveChanges());
    }
    else
    {
        return Task.FromResult(0);
    }
}
  1. 确保Order Item的保存操作生效:
    检查_stavka_narudzbeServices.AddStavkeNarudzbe方法内部是否调用了SaveChanges(),如果没有,需要补充保存逻辑,或者统一在所有操作完成后调用保存(建议用事务保证原子性)。

  2. 可选:用事务封装完整操作
    如果需要保证Order和Order Item要么同时保存成功、要么都失败,可使用EF事务包裹:

using (var transaction = await _dbContext.Database.BeginTransactionAsync())
{
    try
    {
        // 保存Order
        await _narudzbaServices.AddNarudzbuAsync(narudzba);

        // 保存Order items
        foreach (var jelo in _selectedFoodItems)
        {
            Stavka_narudzbe stavka_Narudzbe = new Stavka_narudzbe
            {
                kolicina = "1",
                prilagodbe = null,
                Narudzba_id_narudzba = narudzba.id_narudzba,
                Jelo_id_jelo = jelo.id_jelo,
                Pice_id_pice = null
            };
            await _stavka_narudzbeServices.AddStavkeNarudzbeAsync(stavka_Narudzbe);
        }

        await transaction.CommitAsync();
    }
    catch (Exception)
    {
        await transaction.RollbackAsync();
        throw;
    }
}

内容的提问来源于stack exchange,提问作者GGs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 19:52:37