Возникли проблемы при попытке удалить объект POCO в Entity Framework CTP5 - PullRequest
2 голосов
/ 31 января 2011

У меня проблема при попытке удалить объект POCO с помощью моего кода Entity Framework CTP5.

Я начну с моего 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) к графу объектов ... но я не могу, потому что он уже существует (existingPoco, который я предварительно загружен). Хорошо ... но я чувствую, что мне не стоит об этом беспокоиться. Как потребитель, я не хочу заботиться об этих ObjectManager'ах и прочем. Я просто хочу, чтобы мое poco просто сохраняло / удаляло.

Как я могу изменить свой метод удаления, чтобы отразить эти сценарии? Пожалуйста?

1 Ответ

1 голос
/ 31 января 2011

Вы правы.Удаление - это просто обертка вокруг 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
}
...