在我的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;实体状态跟踪图形,然后将非新实体的状态设置为“未更改”。或者'修改'酌情。
有人可以解释我应该如何更新我的数据库吗?
答案 0 :(得分:1)
问题是检索Currency
项的查询已经在跟踪实体的上下文中填充了图形。因此,您可以手动更新现有属性(即item.Name = currency.Name;
等),这是相当费力的,或者您可以使用AsNoTracking()
停止跟踪实体:
var results = db.Set<Currency>().AsNoTracking().Where(...);
// ^^^^^^^^^^^^^^