违反主键 Entity Framework Code First
Violation of primary key Entity Framework Code First
我已经开始使用 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 保存到数据库时,出现此错误:
Violation of PRIMARY KEY constraint 'PK_dbo.AModels'. Cannot insert
duplicate key in object 'dbo.AModels'. The duplicate key value is
(48ee1711-8da4-46c1-a714-19e985211fed).\r\nThe statement has been
terminated.
我以为这样就能解决
modelBuilder.Entity<BModel>().HasRequired(t => t.Model).WithMany();
但看起来我完全迷路了。谁能帮我解决这个简单的例子?
您的评论揭示了重要信息。当您将该 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;
我已经开始使用 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 保存到数据库时,出现此错误:
Violation of PRIMARY KEY constraint 'PK_dbo.AModels'. Cannot insert duplicate key in object 'dbo.AModels'. The duplicate key value is (48ee1711-8da4-46c1-a714-19e985211fed).\r\nThe statement has been terminated.
我以为这样就能解决
modelBuilder.Entity<BModel>().HasRequired(t => t.Model).WithMany();
但看起来我完全迷路了。谁能帮我解决这个简单的例子?
您的评论揭示了重要信息。当您将该 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;