2

我在尝试使用我的 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:ObjectStateManager 中已存在具有相同键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。

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

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

4

1 回答 1

1

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

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

var attached = Context.Set<T>().Local.FirstOrDefault(e => e.Id == entity.Id);
if (attached != null)
{
 // Delete attached
}
else
{
 // Delete entity
}
于 2011-01-31T13:03:44.513 回答