违反主键Entity Framework Code First

Posted

技术标签:

【中文标题】违反主键Entity Framework Code First【英文标题】:Violation of primary key Entity Framework Code First 【发布时间】:2015-06-25 14:57:32 【问题描述】:

我从 C# 开始,我想制作自己的数据库。

我有两个模型

public class AModel 

    public Guid ID  get; private set; 
    public string Name  get; set; 
    public int Count  get; set; 
    public AModel()
    
        this.ID = Guid.NewGuid();
    


public class BModel 

    public Guid ID  get; private set; 
    public string Name  get; set; 
    public AModel Model  get; set; 
    public BModel()
    
        this.ID = Guid.NewGuid();
    

当我尝试将 BModel 保存到 DB 时,我收到此错误:

违反主键约束“PK_dbo.AModels”。无法插入 对象“dbo.AModels”中的重复键。重复键值为 (48ee1711-8da4-46c1-a714-19e985211fed)。\r\n语句已 终止。

我以为这样就解决了

modelBuilder.Entity<BModel>().HasRequired(t => t.Model).WithMany();

但看起来我完全迷路了。有人可以帮我做这个简单的例子吗?

【问题讨论】:

错误消息很隐秘,因为在天文数字上不太可能出现带有 Guid 的重复密钥。然而,我怀疑的是,由于映射不正确,它试图创建多个相同的外键。如果你使用modelBuilder.Entity&lt;BModel&gt;().HasRequired(t =&gt; t.Model).WithMany().Map(x =&gt; x.ToTable("BAs"); x.MapLeftKey("BId"); x.MapRightKey("AId"); );会发生什么? 在创建 BModel 时我没有创建新的 AModel 实例,而是从 Combobox 中选择一个已经创建的 AModel 实例。我只是希望它创建从 BModel 到 AModel 的引用。 这将如何工作?每次创建新模型时,您都会创建一个新的 GUID。并且有一个私人套装。当它从数据中获取模式时,它将如何为 ID 赋值? 【参考方案1】:

您的评论揭示了重要信息。当您将该 AModel 从您的组合框添加到您的 BModel 时,到那时它将与您的 DbContext 分离。然后,当您将其添加到模型中时,Entity Framework 会认为您有一个新对象。

由于您已将 Id 配置为 DatabaseGenerationOptions.None,因此它将使用您自己提供的主键。在您的情况下,这是分离对象的 PK。因此,当 EF 尝试插入此条目时,它将抛出上述异常,因为具有该键的实体已在其中。

有几种方法可以解决这个问题:

检索现有实体

该实体将在检索时附加到您的上下文中,允许您使用它。然而,这意味着额外的查找:首先将它们放入组合框中,然后使用组合框中实体的 Id 从数据库中再次检索它。

示例用法:

AModel Get(AModel detachedModel)

    using(var context = new MyContext())
    
        return context.AModels.Single(x => x.ID == detachedModel.ID);
    

附加现有模型

这应该只是让 Entity-Framework 知道实体已经存在于数据库中。

using(var context = new MyContext())

    context.AModels.Attach(detachedModel);

其他附加方法是将状态设置为未更改

context.Entry(detachedModel).State = EntityState.Unchanged;

或已修改(如果您还更改了值)

context.Entry(detachedModel).State = EntityState.Modified;

【讨论】:

谢谢,我用 State Unchanged 解决了这个问题,它可以按我的意愿工作。 似乎他们竭尽全力使这对 ajax 非常不友好。我建议不要使用复杂的模型。似乎对我很有帮助。

以上是关于违反主键Entity Framework Code First的主要内容,如果未能解决你的问题,请参考以下文章

Entity Framework 4.1 RTW Code First - POCO 一对多是不是需要引用子实体和子实体主键?

Entity Framework应用:Code First模式数据迁移的基本用法

entity framework Code First 中,对有主外键关联数据怎么更新

Oracle+Entity Framework主键冲突

使用 Entity Framework Core 自动增加部分主键

Entity Framework Core 需要定义一个主键