【问题标题】:Having trouble trying to Delete a POCO object in Entity Framework CTP5尝试在实体框架 CTP5 中删除 POCO 对象时遇到问题
【发布时间】:2011-01-31 08:17:01
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    你是对的。删除只是 Attach 的包装并将状态设置为 Deleted - 这是 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
    }
    

    【讨论】:

    • 嗨 Ladislav,您所说的删除附加或删除实体是什么意思?如何同时实现???
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    相关资源
    最近更新 更多