如何使用DbSet更新数据库

时间:2017-07-23 11:29:46

标签: c# entity-framework dbset

在我的MVC应用程序中,我有一个方法,应该将实体添加到数据库(如果它不存在),或更新它(如果它已经在数据库中)

        //...
        var list = _context.CurrencyRepository.Get().ToList();

        foreach (var currency in currencies)
        {                
            var item = list.FirstOrDefault(c => c.CurrencyId == currency.CurrencyId);

            if (item != null)
            {
                _context.CurrencyRepository.Update(currency);                                                          
            }
            else
            {
                _context.CurrencyRepository.Add(currency);
            }
        }

        _context.CommitChanges();
        //...


    public virtual void Update(T entityToUpdate)
    {
        //both lines fail with the same error message
        _dbSet.Attach(entityToUpdate);
        _dbContext.Entry(entityToUpdate).State = EntityState.Modified;
    }

    public virtual T Add(T entity)
    {
        return _dbSet.Add(entity);
    }

    public void CommitChanges()
    {
        _dbContext.SaveChanges();
    }

它适用于添加,但不幸的是,当我尝试更新时,我收到错误:

  

附加类型'货币'的实体失败,因为同一类型的另一个实体已具有相同的主键值。使用'附加'方法或将实体的状态设置为“未更改”#39;或者'修改'如果图中的任何实体具有冲突的键值。这可能是因为某些实体是新的并且尚未收到数据库生成的键值。在这种情况下,请使用'添加'方法或“添加”#39;实体状态跟踪图形,然后将非新实体的状态设置为“未更改”。或者'修改'酌情。

有人可以解释我应该如何更新我的数据库吗?

1 个答案:

答案 0 :(得分:1)

问题是检索Currency项的查询已经在跟踪实体的上下文中填充了图形。因此,您可以手动更新现有属性(即item.Name = currency.Name;等),这是相当费力的,或者您可以使用AsNoTracking()停止跟踪实体:

var results = db.Set<Currency>().AsNoTracking().Where(...);
//                               ^^^^^^^^^^^^^^