我在尝试使用我的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方法以反映这些情况?请?
答案 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
}