【问题标题】:EF Core - The MERGE statement conflicted with the FOREIGN KEY constraintEF Core - MERGE 语句与 FOREIGN KEY 约束冲突
【发布时间】:2018-10-12 07:54:26
【问题描述】:

我需要一些帮助来了解我在尝试更新产品时遇到的错误。

我已阅读this similar question,并尝试了接受的答案(在每个表之后,在完整产品的最终保存之前放置一个_context.SaveChanges()),但我仍然遇到如下所述的相同错误。

这些是涉及的模型:

public class Product
{
    public int Id { get; set; }
    // some more properties
    public ICollection<IdentifierForProduct> Identifiers { get; set; }
}

public class IdentifierForProduct
{
    public int Id { get; set; }
    public int ProductId { get; set; }
    public int ProductIdentifierId { get; set; }
    public string Value { get; set; } // E.g. "4902505154881"

    public ProductIdentifier Identifier { get; set; }
    public Product Product { get; set; }
}

public class ProductIdentifier
{
    public int Id { get; set; }
    public string Label { get; set; } // E.g. "EAN"

    public ICollection<IdentifierForProduct> ProductIdentifiers { get; set; }
}

最初,在表单发布后,Identifiers 被设置(VMProduct 是产品视图模型):

List<IdentifierForProduct> Identifiers = new List<IdentifierForProduct>();
if (VMProduct.Identifiers != null)
{
    for (var i = 0; i < VMProduct.Identifiers.Count; i++)
    {
        Identifiers.Add(new IdentifierForProduct
        {
            ProductId = VMProduct.Id,
            ProductIdentifierId = VMProduct.Identifiers[i].Id,
            Value = VMProduct.Identifiers[i].Value
        });
    }
}

然后根据表格中所做的更改更改产品属性:

Product DbM = await GetProduct(VMProduct.Id);
// some more properties are set
DbM.Identifiers = Identifiers;
_context.Update(DbM);
await _context.SaveChangesAsync();

await _context.SaveChangesAsync(); 上抛出此异常:

SqlException:MERGE 语句与 FOREIGN KEY 约束“FK_IdentifiersForProducts_ProductIdentifiers_ProductIdentifierId”冲突。冲突发生在数据库“MyStore”、表“dbo.ProductIdentifiers”、列“Id”中。 该语句已终止。 System.Data.SqlClient.SqlCommand+c.b__108_0(任务结果)

DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。 Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch+d__32.MoveNext()

这是GetProduct() 方法:

public async Task<Product> GetProduct(int Id)
{
    Product DbM = await _context.Products
        .Include(ic => ic.InCategories)
            .ThenInclude(pc => pc.ProductCategory)
        .Include(t => t.Type)
            .ThenInclude(i => i.Identifiers) // ProductIdentifiersInTypes
                .ThenInclude(i => i.Identifier)
            .Include(t => t.Type)
                .ThenInclude(p => p.Properties) // ProductPropertiesInTypes
                    .ThenInclude(p => p.Property)
                        .ThenInclude(o => o.Options)
        .Include(p => p.ProductPropertyOptions)
        .Where(p => p.Id == Id)
        .SingleOrDefaultAsync();
    return DbM;
}

【问题讨论】:

  • 如果没有您的数据库架构,很难做到 100%,但您的外键约束冲突。即,您尝试更新表 IdentifiersForProducts 的记录,其中键值 ProductIdentifierId 不在表 ProductIdentifiers 中。假设您的外键使用标准命名约定
  • 您可能正在尝试更新其外键不存在的记录。旁注——而不是你调用_context.Update(DbM),你应该Add/Update标识符。如果关系正确存在,则记录将被保存。
  • 找到解决方案了吗?
  • @BDawg 很抱歉,但我什至不记得我是否解决了它。我已经转向不同的项目。我只是在学习这些东西,还有很长的路要走。

标签: c# asp.net-core entity-framework-core


【解决方案1】:

出现此错误的原因是,您在 'IdentifierForProduct' 中的外键 'ProductIdentifierId' 可能在此处的值为 0:

List<IdentifierForProduct> Identifiers = new List<IdentifierForProduct>();
if (VMProduct.Identifiers != null)
{
    for (var i = 0; i < VMProduct.Identifiers.Count; i++)
    {
        Identifiers.Add(new IdentifierForProduct
        {
            ProductId = VMProduct.Id,
            ProductIdentifierId = VMProduct.Identifiers[i].Id, //here, your id should be 0
            Value = VMProduct.Identifiers[i].Value
        });
    }
}

当实体框架核心遇到外键值为0时,会抛出这种错误,因为它不能插入作为某个对象的主键的外值0。显然,主键不能为 0。

【讨论】:

  • 这对我有帮助,我有一个快速的 for 循环来创建一些示例数据,然后保存到 DB 我得到了这个晦涩的消息。然后我通过您的回答意识到我的 for 循环从 0 开始。#facepalm 谢谢!
猜你喜欢
  • 2019-02-16
  • 1970-01-01
  • 1970-01-01
  • 2019-05-09
  • 2017-02-28
  • 2017-12-28
  • 2022-01-08
  • 1970-01-01
  • 2017-05-07
相关资源
最近更新 更多