EF6无法插入重复的键行

时间:2016-03-18 01:33:56

标签: c# sql-server entity-framework inversion-of-control repository-pattern

当我尝试更新具有唯一约束的实体时出错 我检查了表格,有几个类似的帖子,但没有人回答。

    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'。   声明已经终止。

1 个答案:

答案 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;,如果您这样做,您可能会错误地接近代码。