简体   繁体   English

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

[英]Having trouble trying to Delete a POCO object in Entity Framework CTP5

I'm having a problem trying to delete a POCO object with my Entity Framework CTP5 code. 我在尝试使用Entity Framework CTP5代码删除POCO对象时遇到问题。

I'll start out with my Delete method and then both Integration Tests. 我将从Delete方法开始,然后是两个集成测试。 First Integration Test passes/works, second doesn't. 第一次集成测试通过/有效,第二次没有通过。

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

  ...
}

So that's my generic repo with a Delete method. 这就是我使用Delete方法的通用仓库。

Ok.. now to my Integration Tests.... 好的..现在进行我的集成测试...。

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

that works, this doesn't... 那行得通,这不行...

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

This second one throws the following exception :- 第二个抛出以下异常:

System.InvalidOperationException: An object with the same key already exists in the ObjectStateManager. System.InvalidOperationException:具有相同键的对象已存在于ObjectStateManager中。 The ObjectStateManager cannot track multiple objects with the same key. ObjectStateManager无法使用相同的键跟踪多个对象。

Now, if I understand that correctly, I'm trying to add a second Poco object (ie detachedPoco ) to the Object Graph .. but I can't because one already exists (the existingPoco I pre-loaded). 现在,如果我正确理解,我正在尝试向对象图添加第二个Poco对象(即detachedPoco )..但是我不能,因为一个已经存在(我预先加载了existingPoco Poco)。 Ok ... but I feel like I shouldn't care about this. 好的...但是我觉得我不应该在意这一点。 As a consumer, I don't want to care about these ObjectManagers and stuff. 作为消费者,我不想关心这些ObjectManager和其他东西。 I just want to have my poco's just save/delete. 我只想保存/删除我的poco。

How can I change my Delete method to reflect these scenarios? 如何更改我的Delete方法以反映这些情况? Please? 请?

You are right. 你是对的。 Deleting is just wrapper around Attach and set state to Deleted - it is the only way how ObjectContext (wrapped in DbContext) can know that it has to delete object. 删除只是对Attach的包装,并将状态设置为Deleted-这是ObjectContext(包装在DbContext中)可以知道必须删除对象的唯一方法。

I guess you can try to use new CTP5 feature of DbSet - Local and try to find attached entity with the same Id first: 我想你可以尝试使用新的功能CTP5 DbSet - Local ,并设法找到具有相同ID的第一附着实体:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM