DBContext, состояние и исходные значения - PullRequest
4 голосов
/ 22 сентября 2011

Я работаю с ASP.NET MVC3, используя EF и Code First.

Я пишу простой трекер проблем для практики.В моем контроллере у меня есть довольно стандартный код:

[HttpPost]
public ActionResult Edit(Issue issue) {
    if (ModelState.IsValid) {
        dbContext.Entry(issue).State = EntityState.Modified
        .....
    }
}

Вопрос часть 1 Я пытаюсь разобраться, как работает dbcontext - прежде чем я установлю состояние в dbContext.Entry(проблема), я предполагаю, что мой объект проблемы отсоединен.Как только я устанавливаю состояние, которое нужно изменить, объект присоединяется - но к чему?dbContext или база данных?Мне не хватает того, что на самом деле означает это (прикрепление)?

Вопрос, часть 2 Ради аргумента, скажем, я решил установить поле «Принято» в моей проблеме.Принято логическое значение.Я начинаю с того, что он ложный, я устанавливаю это значение в форме и отправляю.В какой момент мой объект присоединен, в чем смысл коллекции OriginalValues?например, если я устанавливаю точку останова сразу после установки EntityState.Modified, но перед вызовом SaveChanges () я могу запросить

db.Entry(issue).OriginalValues["Accepted"]

, и это даст мне то же значение, что и простой запрос объекта вопроса, который был переданв Edit .... то есть он дает тот же результат, что и

issue.Accepted

Я явно что-то упускаю, потому что в документации сказано: "Исходные значения обычно являются значениями свойств объекта, какими они были в последний раззапрашивается из базы данных. "Но это не тот случай, потому что база данных по-прежнему сообщает о том, что Accepted принят как ложный (да, я заметил слово «обычно» в документации, но мой код в значительной степени стандартно генерируется кодом MS, так что…).Итак, что мне не хватает?что на самом деле здесь происходит?

1 Ответ

3 голосов
/ 22 сентября 2011

Контекст может работать только с присоединенными сущностями.Присоединение означает, что контекст знает об объекте, он может сохранять свои данные, а в некоторых случаях он может предоставлять расширенные функции, такие как отслеживание изменений или отложенная загрузка.

По умолчанию все объекты, загруженные из базы данных экземпляром контекста,прикреплен к этому экземпляру.В случае веб-приложений и других отключенных сценариев у вас есть новый экземпляр контекста для каждого обработанного HTTP-запроса (если вы этого не делаете, вы делаете большую ошибку).Также ваша сущность, созданная связывателем модели в HTTP POST, не загружается этим контекстом - она ​​отсоединяется.Если вы хотите сохранить эту сущность, вы должны прикрепить ее и сообщить контексту об изменениях, которые вы сделали.Установка состояния от Entry до Modified выполнит обе операции - он присоединит сущность к контексту и установит ее глобальное состояние на Modified, что означает, что все скалярные и комплексные свойства будут обновлены при вызове SaveChanges.

Таким образом, установив состояние на Modified, вы прикрепили сущность к контексту, но до тех пор, пока вы не вызовете SaveChanges, это не повлияет на вашу базу данных.

OriginalValues в основном полезно в полностью прикрепленномсценарии, в которых вы загружаете сущность из базы данных и вносите изменения в эту присоединенную сущность.В таком случае OriginalValues показывает значения свойств, загруженных из базы данных, а CurrentValues показывает фактические значения, установленные вашим приложением.В вашем сценарии контекст не знает исходных значений.Он считает, что исходные значения - это те, которые использовались при присоединении сущности.

...