尝试在Entity Framework CTP5中删除POCO对象时遇到问题

时间:2011-01-31 08:17:01

标签: .net entity-framework poco entity-framework-ctp5

我在尝试使用我的Entity Framework CTP5代码删除POCO对象时遇到问题。

我将从我的Delete方法开始,然后是两个集成测试。第一次集成测试通过/工作,第二次没有。

public class GenericRepository<T> : IRepository<T> where T : class
{
  public GenericRepository(DbContext unitOfWork)
  {
    Context = unitOfWork;
  }

  ...

  public void Delete(T entity)
  {
    if (entity == null)
    {
      throw new ArgumentNullException("entity");
    }

    if (Context.Entry(entity).State == EntityState.Detached)
    {
      Context.Entry(entity).State = EntityState.Deleted;
    }
    Context.Set<T>().Remove(entity);
  }

  ...
}

这是我使用Delete方法的通用仓库。

好的..现在进行我的集成测试......

[TestMethod]
public void DirectlyDeleteAPoco()
{
  // Arrange.
  var poco = new Poco {PocoId = 1};

  // Act.
  using (new TransactionScope())
  {
    PocoRepository.Delete(poco);
    UnitOfWork.Commit();

    // Now try and reload this deleted object.
    var pocoShouldNotExist =
      PocoRepository.Find()
      .WithId(1)
      .SingleOrDefault();

    Assert.IsNull(pocoShouldNotExist);
  }
}

有效,但不是......

[TestMethod]
public void DeleteAPocoAfterLoadingAnInstance()
{
  // Arrange.
  var existingPoco = PocoRepository.Find().First();
  var detachedPoco = new Poco {PocoId = existingPoco.PocoId};

  // Act.
  using (new TransactionScope())
  {
    PocoRepository.Delete(detachedPoco );
    UnitOfWork.Commit();

    // Now try and reload this deleted object.
    var pocoShouldNotExist =
      PocoRepository.Find()
      .WithId(existingPoco.PocoId)
      .SingleOrDefault();

    Assert.IsNull(pocoShouldNotExist);
  }
}

第二个引发以下异常: -

  

System.InvalidOperationException:An   具有相同键的对象   存在于ObjectStateManager中。该   ObjectStateManager无法跟踪   具有相同键的多个对象。

现在,如果我理解正确,我正在尝试将第二个Poco对象(即detachedPoco)添加到对象图...但我不能,因为一个已经存在({{1}我预装了)。好的......但我觉得我不应该关心这个。作为消费者,我不想关心这些ObjectManagers和东西。我只想让我的poco只是保存/删除。

如何更改我的Delete方法以反映这些情况?请?

1 个答案:

答案 0 :(得分:1)

你是对的。删除只是包装附件并将状态设置为已删除 - 这是ObjectContext(包装在DbContext中)如何知道它必须删除对象的唯一方法。

我想您可以尝试使用DbSet - Local的新CTP5功能,并尝试首先找到具有相同ID的附加实体:

var attached = Context.Set<T>().Local.FirstOrDefault(e => e.Id == entity.Id);
if (attached != null)
{
 // Delete attached
}
else
{
 // Delete entity
}