我正在尝试更新我的数据库中的实体,但是当我尝试这样做时,我收到错误提示Violation of PRIMARY KEY constraint 'PK_Units'. Cannot insert duplicate key in object 'dbo.Units'.
我不是要尝试使用已存在的密钥插入新数据。我只是试图从数据库中检索已存在的项目,修改它,然后更新它。
这里是执行此操作的代码:
// Get an already existing unit from the repository
Unit existingUnit = pacificRepo.GetUnit(unit.c_number);
// Update a few values of this existing unit
existingUnit.serial_number = unit.serial_number;
existingUnit.country = unit.country;
existingUnit.geo_location = unit.geo_location;
// Commit the changes to the repository
pacificRepo.UpdateUnit(existingUnit);
上面使用的支持GetUnit()函数非常简单:
public Unit GetUnit(string c_number)
{
return context.Units.FirstOrDefault(u => u.c_number == c_number);
}
以下是有问题的功能:
public bool UpdateUnit(Unit u)
{
try
{
context.Entry(u).State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();
return true;
}
catch (Exception e)
{
return false; // Violation of PRIMARY KEY ....
}
}
编辑:这是单元类
public class Unit
{
[Key]
public string c_number { get; set; }
public string serial_number { get; set; }
public string ip_address { get; set; }
public string build_version { get; set; }
public string country { get; set; }
public DbGeography geo_location { get; set; }
public string location_at_address { get; set; }
public int deployment_status { get; set; }
public string short_description { get; set; }
public string notes { get; set; }
public int contact_id { get; set; }
public int reg_contact_id { get; set; }
public int network_id { get; set; }
...
}
数据库:
CREATE TABLE [dbo].[Units] (
[c_number] NVARCHAR (45) NOT NULL,
[serial_number] NVARCHAR (45) NULL,
[ip_address] NVARCHAR (45) NOT NULL,
[build_version] NVARCHAR (45) NOT NULL,
[geo_location] [sys].[geography] NULL,
[location_at_address] NVARCHAR (45) NULL,
[deployment_status] INT NOT NULL,
[short_description] NVARCHAR (255) NULL,
[notes] TEXT NULL,
[contact_id] INT NULL,
[reg_contact_id] INT NULL,
[network_id] INT NULL,
[country] NVARCHAR (45) NULL,
CONSTRAINT [PK_Units] PRIMARY KEY CLUSTERED ([c_number] ASC)
);
有谁知道为什么会这样?我没有尝试添加()它,我试图将其状态设置为修改。
答案 0 :(得分:0)
只是为了笑,试着评论这一行
context.Entry(u).State = System.Data.Entity.EntityState.Modified;
你不应该设置状态,EF应该跟踪它。当然,假设在检索实体和更新实体之间,上下文不会超出范围。如果是,您需要在Units
中再次检索UpdateUnit
对象,然后通过将传入对象中的值传输到检索到的对象来应用更改。
我很好奇,这是两周内我第二次看到SO上的代码,它明确地设置了对象的State
。是否有最近出现的文章或博客文章显示你应该这样做什么?
答案 1 :(得分:0)
替换以下行
context.Entry(u).State = System.Data.Entity.EntityState.Modified;
带
context.Unit.Attach(u);
PS。您的实体可能处于Detached
状态。