【问题标题】:The instance of entity type 'xTestType' cannot be tracked because another instance of this type with the same key is already being tracked?无法跟踪实体类型“xTestType”的实例,因为已经在跟踪具有相同键的该类型的另一个实例?
【发布时间】:2017-10-12 14:36:51
【问题描述】:

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

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.

【问题讨论】:

  • 您可能需要附加到 xTextType 实体,因为它已经被跟踪,然后您应该能够成功删除它。但是,我不明白为什么当你已经有一个引用时实例化一个新的 xTestType() (如错误消息所示)
  • 错误信息一目了然。输入由上下文跟踪(并因此附加到)。然后您创建另一个具有相同 id 值的条目并尝试删除它,显然它必须附加到上下文中。为什么 id 值总是 0 很难说,和这个错误无关。可能您使用身份插入保存了该值,或者从未将该值保存到您的数据库中,但是您在本地 DbContext 实例中进行了所有更改。
  • 你没有在new xTestType()中设置Id?
  • 你有什么办法@aaron ?
  • 你没有在new xTestType()中设置Id?

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


【解决方案1】:

当您从数据库中获取数据并对其进行迭代时,例如:

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);
}

【讨论】:

    【解决方案2】:

    存在问题是因为当您获取所有实体框架时,实体框架正在跟踪 xTestType。有两种方法可以处理这种情况。

    方法一:

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

    方法二:

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

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

    【讨论】:

      猜你喜欢
      • 2016-08-19
      • 1970-01-01
      • 2022-01-02
      • 1970-01-01
      • 2021-11-24
      • 2020-10-16
      • 2018-12-01
      • 2021-08-27
      • 1970-01-01
      相关资源
      最近更新 更多