开发者

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

开发者 https://www.devze.com 2023-02-07 10:02 出处:网络
I\'m having a problem trying to delete a POCO object with my Entity Framework CTP5 code. I\'ll start out with my Delete method and then both Integration Tests. First Integration Test passes/works, se

I'm having a problem trying to delete a POCO object with my Entity Framework CTP5 code.

I'll start out with my Delete method and then both Integration Tests. 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.

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. The ObjectStateManager cannot track multiple objects with the same key.

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). Ok ... but I feel like I shouldn't care about this. As a consumer, I don't want to care about these ObjectMan开发者_高级运维agers and stuff. I just want to have my poco's just save/delete.

How can I change my Delete method to reflect these scenarios? 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.

I guess you can try to use new CTP5 feature of DbSet - Local and try to find attached entity with the same Id first:

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号