3

I'm trying to delete multiple rows from a table. But it gives the following error after the first iteration. I can see primary key Id as 0 on all the xTestType object. that might be the issue. Why is it always giving 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);
  }
}

Exception:

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.

Andre Odendaal
  • 557
  • 6
  • 19
Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
  • You probably need to attach to the xTextType entity since its already being tracked and then you should be able to delete it successfully. However, i do not follow why you instantiate a new xTestType() when you already have a reference (as the error message suggests) – Digvijay Oct 12 '17 at 14:48
  • the error message is self explanatory. input is tracked (and therefore attached to) by the context. and you create another entry with the same id value and try to delete that, for which it obviously has to be attached to the context. why the id value is always 0 is hard to tell, it has nothing to do with this error. probably you saved the value with identity insert or never saved the value to your database, but did all your changes within your local DbContext instance. – DevilSuichiro Oct 12 '17 at 15:09
  • You didn't set `Id` in `new xTestType()`? – aaron Oct 12 '17 at 16:21
  • Do you have any approach @aaron ? – Vivek Nuna Oct 31 '17 at 02:32
  • You didn't set `Id` in `new xTestType()`? – aaron Oct 31 '17 at 02:45
  • That's not the recommended way – Vivek Nuna Oct 31 '17 at 02:48
  • Your `if` evaluates things that do not change between interations of your `foreach`. That is very weird. You'll end up either _never or always_ executing the if's code block. It's also very weird that you keep trying to delete several `xTestType` objects with **the same ID** but a different TestTypeMasterId. This is likely the cause of the error, but the solution is not obviously readable from your example. You need to recheck your code. – Flater Apr 23 '18 at 10:55

2 Answers2

7

When you fetch data from database, and iterate over it, like:

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

}

do not create another object, pass the fetched object directly to Delete or use it to update, because DbContext is tracking the objects it has fetched, not the ones you create. for example:

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

you must pass the originally fetched instance to Remove() method, see:

var dataObject = await dbContext.Table.where(x=>x.UserId == model.UserId).TolistAsync();
foreach(var item in dataObject)
{ 
    dbContext.Table.Remove(item);
}
Alireza
  • 5,421
  • 5
  • 34
  • 67
AmirReza-Farahlagha
  • 1,204
  • 14
  • 26
5

The issue exists because the entity framework is tracking xTestType when you fetched all of them. There are two approaches to handle the situation.

Approach 1:

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

Approach 2 :

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

I would say the first approach is the best one.

Rudresha Parameshappa
  • 3,826
  • 3
  • 25
  • 39