AsNoTracking and Remove

时间:2017-04-20 18:22:27

标签: c# entity-framework

我正在尝试使用此代码从数据库中删除一行

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

在删除时出现此错误

  

System.InvalidOperationException:无法删除该对象,因为在ObjectStateManager中找不到该对象。

我试图将实体图片附加到图片

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

这是错误:

  

System.InvalidOperationException:附加类型为' Album.DatabaseContext.ListPicture'的实体。失败,因为同一类型的另一个实体已具有相同的主键值。

我的应用程序中多次使用GetPicture函数,如何解决此问题

3 个答案:

答案 0 :(得分:1)

嗯,显然必须在上下文中跟踪(加载)实体。

所以要么不要使用GetPicture方法(我知道,代码重复但是......):

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

PicturesDbSet<T>(如发布的代码所示),您可以使用Find方法代替:

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

这两种方法都将确保返回的实例附加到上下文。

答案 1 :(得分:0)

使用AsNoTracking时,EF不会为已加载到代理中的实体维护数据。也就是说,它是一个不再依赖于EF的实体。

但是,该实体存在于数据库中。 尝试执行Attach时,EF会检查已存在具有相同Id的某人并抛出异常。

我的建议是:

1:从GetPicture方法中删除AsNoTracking。 2:如果你不能,请按照以下方式制作删除方法:

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

答案 2 :(得分:0)

如果您不确定是否会附加(并且基于您获得的例外情况可能是),那么您可以添加对DbContext的检查实例以查看它是否已附加,如果不附加则附加它。这需要访问正在使用的DbContext实例。

或者,请确保始终返回附加实体,并且不要使用AsNoTracking()

public void DeletePicture(string Id)
{
  ListPicture pic = GetPicture(Id);
  if( pic != null)
  {
      // add check if instance is attached
      if(contextInstance.Entry(pic).State == System.Data.Entity.EntityState.Detached)
        Pictures.Attach(pic);
      Pictures.Remove(pic);
   }
   SaveChanges(); // this could be moved to inside the if block
}