Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AsNoTracking and Remove

I am trying to delete a row from the Database usin this code

public ListPicture GetPicture(string Id)
{
  ListPicture pic = Pictures.AsNoTracking().FirstOrDefault(x => x.pId == Id);
  return pic;
}

public void DeletePicture(string Id)
{
  ListPicture pic = GetPicture(Id);
  if( pic != null)
  {
     Pictures.Remove(pic);
  }
  SaveChanges();
}

On remove I have this error

System.InvalidOperationException: The object cannot be deleted because it was not found in the ObjectStateManager.

I tried to attached the entity pic to Pictures

public void DeletePicture(string Id)
{
  ListPicture pic = GetPicture(Id);
  if( pic != null)
  {
      Pictures.Attach(pic);
      Pictures.Remove(pic);
   }
   SaveChanges();
 }

this is the error is :

System.InvalidOperationException: Attaching an entity of type 'Album.DatabaseContext.ListPicture' failed because another entity of the same type already has the same primary key value.

the function GetPicture is used many times in my application, how can I resolve this issue

like image 679
melom Avatar asked Jul 01 '26 18:07

melom


2 Answers

When you use AsNoTracking, EF does not maintain data for entities that have been loaded into the proxy. That is, it is an entity that no longer relies on EF for anything.

However, this entity exists in the database. When attempting to execute an Attach, the EF checks that there already exists someone with the same Id and throws the exception.

My suggestion is:

1: Remove the AsNoTracking from GetPicture method. 2: If you cannot, make your Delete method like this:

public ListPicture GetPicture(string Id)
{
    ListPicture pic = Pictures.AsNoTracking().FirstOrDefault(x => x.pId == Id);
    return pic;
}

public void DeletePicture(string Id)
{
    ListPicture pic = Pictures.Find(id);
    if( pic != null)
    {
       Pictures.Remove(pic);
    }
    SaveChanges();
}
like image 80
Jedi31 Avatar answered Jul 03 '26 19:07

Jedi31


Well, apparently the entity has to be tracked (loaded) in the context.

So either don't use the GetPicture method (I know, code duplication but...):

ListPicture pic = Pictures.FirstOrDefault(x => x.pId == Id);
if (pic != null)
{
    Pictures.Remove(pic);
}
SaveChanges();

or if the Pictures is DbSet<T> (as it seems from the posted code), you can use the Find method instead:

ListPicture pic = Pictures.Find(Id);
if (pic != null)
{
    Pictures.Remove(pic);
}
SaveChanges();

Both approaches will ensure the returned instance is attached to the context.

like image 45
Ivan Stoev Avatar answered Jul 03 '26 19:07

Ivan Stoev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!