当我尝试更新具有唯一约束的实体时出错 我检查了表格,有几个类似的帖子,但没有人回答。
public class Car
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdCar { get;set; }
public string ColorCode { get; set; }
[Index(IsUnique = true)]
public string MotorId { get; set; }
}
private static int UpsertCar(Car checkCar, IUow uow)
{
var car =
uow.Cars.GetAll().FirstOrDefault(x => x.MotorId.Trim()
.Equals(checkCar.MotorId.Trim(),
StringComparison.CurrentCultureIgnoreCase));
if (car == null)
{
uow.Cars.Add(checkCar);
uow.Commit();
return checkCar.IdCar;
}
else
{
car.ColorCode = checkCar.ColorCode;
uow.Cars.Update(car);
uow.Commit(); // Issue when i try to save
return car.IdCar;
}
}
这是更新功能
public virtual void Update(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
if (dbEntityEntry.State == EntityState.Detached)
{
DbSet.Attach(entity);
}
dbEntityEntry.State = EntityState.Modified;
}
错误
无法在对象' dbo.Car'中插入重复的键行。具有唯一索引' IX_MotorId'。 声明已经终止。
答案 0 :(得分:0)
这里的问题是您选择在实体框架顶部使用存储库模式 - 一个架构问题。这不是您在解决方案中遇到的唯一问题。
EF6非常强大,存储库模式隐藏了所有这些功能。
编码整个upsert概念的标准方法是从上下文中加载原始记录:
public class Car
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdCar { get;set; }
public string ColorCode { get; set; }
[Index(IsUnique = true)]
public string MotorId { get; set; }
//By having this update function alongside the members, it's easy to see whether it's up to date.
public void Update(Car original)
{
original.ColorCode = ColorCode;
original.MotorId = MotorId;
}
}
public static int UpsertCar(Car checkCar, MyContext db)
{
var original = db.Cars.SingleOrDefault(c => c.IdCar == checkCar.IdCar);
if (original == null)
{
db.Cars.Add(checkCar);
}
else
{
checkCar.Update(original);
}
db.SaveChanges();
}
在这里,您可以看到直接使用EntityFramework时的简单程度。
重要的是,您还可以看到创建自己的Update函数是多么简单(保持当前的ORM架构)。通常,业务规则将限制可以更新的内容,并且您自己的更新功能不允许更新所有字段。
您永远不需要使用dbEntityEntry.State = EntityState.Modified;
,如果您这样做,您可能会错误地接近代码。