违反 PRIMARY KEY 约束“[Table_id]”。使用实体框架时无法在对象“[Table_id]”中插入重复键

Posted

技术标签:

【中文标题】违反 PRIMARY KEY 约束“[Table_id]”。使用实体框架时无法在对象“[Table_id]”中插入重复键【英文标题】:Violation of PRIMARY KEY constraint '[Table_id]'. Cannot insert duplicate key in object '[Table_id]' when using Entity Framework 【发布时间】:2017-10-10 23:57:57 【问题描述】:

看起来很简单,但我在这方面遇到了重大问题。 我正在使用 Entity Framework 6 并且在将一个对象关联到另一个对象时遇到问题。在我的应用程序中,我想添加一个带有新的连接地址的新人员记录,该地址与现有地址类型(“邮寄”、“个人”等)相关联 例如,将具有现有 AddressType 的新地址记录分配给居民。

var person = new Person();
var address = new Address();

address.AddressType = _systemService.GetAddressType(addressTypeId); 
person.Addresses.Add(address);
_personService.SavePerson(person);

在 SavePerson() 中提交对 DBContext 的更改会引发以下错误:

违反主键约束“PK_dbo.AddressTypes”。不能 在对象“dbo.AddressTypes”中插入重复键。

这应该很简单,但它不起作用。让我向您展示我如何检索AddressType 以及如何保存Person

    public AddressType GetAddressType(Guid id)
    
        var addressType = _repositoryContainer.AddressType.Get(id);
        return addressType;
    

    public Person SavePerson(Person person)
                
      _repositoryContainer.Person.Add(person);
      _repositoryContainer.CommitChanges();
       return person;
    

就 DBContext 而言,我将同一个存储库容器传递给单个存储库容器,然后应用程序将其用于所有数据库操作。 :

 public class RepositoryContainer : IRepositoryContainer
    
        private readonly MyDBContext _dbContext;

        public RepositoryContainer(MyDBContext dbContext)
        
            _dbContext = dbContext;
            //initiating repositories here
            .
            .
        
     

如何在我的应用程序中添加一个具有现有地址类型的地址的新人?我已经做了很多次,但不知道为什么会在这个简单的场景中出现问题。

【问题讨论】:

您的 GetAddressType() 方法返回现有记录。您不能将相同的记录添加到数据库中。你清楚你想要做什么,但如果你想用现有的AddressType 保存Person,然后在Person 中设置适当的属性并保存,而不是添加AddressType @StephenMuecke 我对你说的有点困惑。部分原因是我习惯了 Nhibernate 在识别现有“会话”并允许我将它们连接到新的对象实例方面做得很好。如何将现有类型与 EF 中的新对象以及我的场景相关联? 我仍然不确定您想要做什么。展示你的模型可能会更清楚 @StephenMuecke 我想添加一个新的个人记录,带有一个新地址,但地址将是现有类型(“邮寄”、“个人”等) 新地址还是现有地址(问题的最后一段指出将其与现有的地址关联)? 【参考方案1】:

嗯,这条线怎么样:

#original
person.Addresses.Add(Address);

不应该是这样的吗?:

#my
person.Addresses.Add(address);

不同之处在于地址字段中的 A。原始是指一种类型。我的变量名。一般来说,具有与对象类型相同的 var 名称不是一个好主意。但也许不是……

【讨论】:

是的,我认为在我上面的例子中这是一个明显的错字。 不,这不是答案。【参考方案2】:

您问:“我如何在我的应用程序中添加一个具有现有地址类型的地址的新人?”答案是:person.Addresses.Add(address);

你得到的错误 Violation of PRIMARY KEY constraint 'PK_dbo.AddressTypes'. Cannot insert duplicate key in object 'dbo.AddressTypes'. 是因为调用 person.Addresses.Add(Address);创建一个 id 为 null/0 的地址(我们需要确定您的 mysql 架构),并且由于您多次运行它,您无法插入重复的密钥。这是因为实体框架会自动创建附加到实体(人员)的对象(地址),并在您添加人员时尝试将它们插入数据库。使用地址而不是地址传递现有的 id 并且不会发生插入。

【讨论】:

以上是关于违反 PRIMARY KEY 约束“[Table_id]”。使用实体框架时无法在对象“[Table_id]”中插入重复键的主要内容,如果未能解决你的问题,请参考以下文章

数据导入时违反 PRIMARY KEY 约束错误

交叉应用和外部应用一起使用时违反 PRIMARY KEY 约束

违反 PRIMARY KEY 约束“PK_Address”。等等......我做错了啥?

违反 PRIMARY KEY 约束“PK_EMPLOYEE”。无法在对象中插入重复键

使用实体框架添加记录时违反链接记录的PRIMARY KEY约束

(转)sql 违反了 PRIMARY KEY 约束,不能在对象 中插入重复键