无法跟踪实体类型'xTestType'的实例,因为已经跟踪了具有相同密钥的此类型的另一个实例?

时间:2017-10-12 14:36:52

标签: c# entity-framework asp.net-core entity-framework-core aspnetboilerplate

我正在尝试从表中删除多行。但它在第一次迭代后出现以下错误。我可以在所有Id对象上看到主键0xTestType。这可能是问题所在。为什么总是提供Id 0

foreach (var temp in oldxDetails.TestTypes)
{
  if (deleteTestTypes.Contains(input.Id))
  {
    var xTestType = new xTestType
    {
      xId = xId,
      TestTypeMasterId = temp.Id
    };

    await _xTestRepository.DeleteAsync(xTestType);
  }
}

例外:

The instance of entity type 'xTestType' cannot be tracked because another instance of this type with the same key is already being tracked. When adding new entities, for most key types a unique temporary key value will be created if no key is set (i.e. if the key property is assigned the default value for its type). If you are explicitly setting key values for new entities, ensure they do not collide with existing entities or temporary values generated for other new entities. When attaching existing entities, ensure that only one entity instance with a given key value is attached to the context.

2 个答案:

答案 0 :(得分:5)

这是因为当您获取所有这些实体框架时,实体框架正在跟踪xTestType。有两种方法可以解决这种情况。

方法1:

DbContext.Entry(xTestTypeOld).State = EntityState.Deleted;  // where xTestTypeOldis record from which you are taking xId

方法2:

DbContext.Entry(xTestTypeOld).State = EntityState.Detached;
DbContext.Entry(xTestType).State = EntityState.Deleted;

我想说第一种方法是最好的方法。

答案 1 :(得分:5)

从数据库中获取数据并迭代它时,如:

var dataObject = await dbContext.Table.where(x=>x.UserId == model.UserId).TolistAsync();
foreach(var item in dataObject)
{ 

}

不创建另一个对象,将获取的对象直接传递给Delete或使用它进行更新,因为DbContext正在跟踪它所获取的对象,而不是您创建的对象。例如:

//Wrong code
var dataObject = await dbContext.Table.where(x=>x.UserId == model.UserId).TolistAsync();
foreach(var item in dataObject)
{ 
   var x=new DataObject()
   {
      x=item.Id
   };
   dbContext.Table.Remove(x);
}

您必须将最初提取的实例传递给Remove()方法,请参阅:

var dataObject = await dbContext.Table.where(x=>x.UserId == model.UserId).TolistAsync();
foreach(var item in dataObject)
{ 
    dbContext.Table.Remove(item);
}