1

Я использую шаблон хранилища и делаю вещи централизованными. Я создал интерфейс IValidate, который может реализовать каждый из моих репозиториев. В этом я делаю проверки сущности в зависимости от их состояния. До сих пор так хорошо, пока я не удалил сущность. Когда я попытался получить доступ к объекту из удаленного объекта, я получил исключение, объект больше не был в контексте.Как сохранить данные после DbSet.Remove?

Ex:

class A 
{ 
    int MyClassBId 
    B MyClassB 
} 

Если добавить или обновить объект A я могу получить доступ A.MyClassB без каких-либо хлопот. Но если я удалю (DbSet.Remove) даже до вызова SaveChanges (мой подход, конечно, вызывает эту проверку перед сохранением), ссылки равны нулю. Поэтому, если я попытаюсь получить доступ к A.MyClassB снова, я получаю нулевую ссылку, но там есть объекты, не имеющие ленивых нагрузок. Например, A.MyClassBId по-прежнему имеет FK для B.

Я понял, что DbSet.Remove отмечает только объект для удаления, ничего другого. Удаляет ли это и из контекста? Как я могу это решить? Вызовите DbSet.Remove и все еще поддерживайте ссылки в объекте, по крайней мере до тех пор, пока не будет вызван SaveChanges?

Спасибо.

ответ

1

Вы должны понимать, что два процесса идут:

  1. Entity Framework отслеживает лиц, которые загружаются в DbContext, сохраняя свое состояние как Added, Modified, Deleted или Unchanged. Вы можете проверить это с помощью вызова MyDataContext.Entry(MyEntity).State.
  2. Внешне классы POCO ведут себя так же, как вы ожидаете от классов, которые не имеют никакого отношения к ORM вообще.

Итак, что происходит, когда вы вызываете метод DbSet.Remove, это то, что объект будет помечен для удаления под обложками, а внешне он будет удален из ICollection, к которому он принадлежал.

Если вы хотите, чтобы следить за лиц, которые должны быть удалены на SaveChanges вызова вам придется определить WillBeDeleted собственности на сущности и ваш код будет принимать это свойство во внимание при подсчете активных объектов, проверки и т.д. . Фактический вызов DbSet.Remove должен быть выполнен непосредственно перед вызовом SaveChanges.

В качестве альтернативы вы можете использовать MyDataContext.Configuration.AutoDetectChangesEnabled=False перед инициализацией DbContext. Теперь объект, который подвергается методу DbSet.Remove, не будет удален из его ICollection в классе POCO, но вы не знаете, что сущность должна быть удалена без повторного отслеживания этого в собственном свойстве.

+0

Я подумал об этом, добавив свойство на каждый класс POCO, но это показалось несколько дорогим. Я ошибаюсь? О втором предположении, если я установил, что мне также понадобится дополнительное свойство, и я не хотел бы останавливать EF от отслеживания изменений. Жду твоего ответа. Спасибо за ответ. – eestein

+0

Было бы немного дороже, если новое свойство 'WillBeDeleted' внесет его в базу данных, что не является необходимым. Вы можете предотвратить это путем аннотации свойства как ''. Стоимость связана с необходимостью учитывать свойство 'WillBeDeleted' в каждом перечислении или считать, что вы делаете объект. Я, по крайней мере, не видел этого, и из-за этого мне пришлось исправить множество ошибок, но мы его внедрили. – Dabblernl

+0

Об остановке EF от отслеживания изменений: это очень хорошая идея во многих сценариях, так как она может улучшить производительность, но я согласен, что ее отключение по умолчанию является неразумным. – Dabblernl