Entity Framework Service Layer Обновление POCO - PullRequest
3 голосов
/ 22 апреля 2011

Я использую подход Service Layer --> Repository --> Entity Framework (Code-First) w/POCO objects, и мне сложно обновлять сущности.

Я использую AutoMapper для сопоставления моих доменных объектов с моими моделями представления, и это хорошо работает для получения данных, нет, как мне получить эти изменения обратно в базу данных?

Используя чистые объекты POCO, я бы предположил, что отслеживания изменений не существует, поэтому я вижу, что мой единственный вариант - это обрабатывать его самостоятельно. Вы просто убедитесь, что ваши View модели имеют ТОЧНО те же свойства, что и ваши доменные объекты? Что если я просто поменяю поле или два в модели просмотра? Не будут ли остальные поля в доменном объекте перезаписаны в базе данных значениями по умолчанию?

С учетом сказанного, что является лучшим подходом?

Спасибо!

Редактировать

Итак, на чем я спотыкаюсь, давайте возьмем, к примеру, простой Customer:

1) У Controller есть служба CustomerService, которая вызывает метод GetCustmoerByID служб.

2) Service вызывает CustomerRepository и получает объект Customer.

3) Controller использует AutoMapper для сопоставления Customer с ViewModel.

4) Controller передает модель View. Все отлично!

Теперь в представлении вы делаете некоторые модификации клиента и отправляете его обратно на контроллер, чтобы сохранить изменения в базе данных.

Я бы предположил, что в этот момент объект отделен. Так должна ли модель иметь ТОЧНЫЕ свойства, аналогичные объекту Customer? И нужно ли вам создавать скрытые поля для каждого элемента, который вы не хотите показывать, чтобы они могли сохраняться обратно?

Как вы справляетесь с сохранением объекта обратно в базу данных? Что произойдет, если ваш вид / модель имеет дело только с парой полей объекта?

Ответы [ 3 ]

5 голосов
/ 22 апреля 2011

Если вы используете EF Code First, то есть API-интерфейс DbContext, то у вас все еще есть отслеживание изменений, о котором заботится ваш контекстный класс.

после внесения изменений в ваши объекты все, что вам нужно сделать, это вызвать SaveChanges() в вашем контексте, и это сохранит изменения в вашей базе данных.

EDIT

Поскольку вы создаете «копию» сущности с помощью AutoMapper, она больше не присоединяется к вашему контексту.

Я думаю, что вы могли бы сделать что-то похожее на то, что вы сделали бы в ASP.NET MVC (с UpdateModel). Вы можете получить исходную сущность из своего контекста, взять вашу ViewModel (которая может содержать измененные свойства) и обновить старую сущность, либо вручную (только измененные свойства), либо с помощью AutoMapper. Затем сохраните изменения, используя context.SaveChanges().

Другим решением было бы отправить объект модели как [часть] ViewModel. Таким образом, ваша сущность будет прикреплена к контейнеру, и отслеживание изменений все равно будет работать.

Надеюсь, это поможет:)

3 голосов
/ 22 апреля 2011

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

Основной подход - просто установить сущность как измененную.Это работает для скалярных и сложных свойств, но не работает для свойств навигации (кроме отношений FK) - для получения дополнительной информации о проблемах со свойствами навигации проверьте этот ответ (он связан с EFv4 и ObjectContext API, но такой жепроблемы с DbContext API).Недостатком этого подхода является то, что все поля в БД будут изменены.Если вы просто хотите изменить одно поле, вам все равно нужно правильно заполнить другие поля, иначе ваша запись в базе данных будет повреждена.

Существует способ явно определить, какие поля изменились.Вы будете устанавливать измененное состояние для каждого свойства вместо целого объекта.Это немного сложнее решить с помощью общего подхода, но я попытался показать какой-то способ для EFv4 и для EFv4.1 .

1 голос
/ 26 августа 2012

Я согласен с @AbdouMoumen, что намного проще использовать объекты модели на уровне представления. Уровень обслуживания должен предоставлять API для сохранения этих объектов в хранилище данных (дБ). Уровень обслуживания не должен тупо дублировать юриста хранилища (т. Е. Сохранить (сущность) для каждой сущности), а должен обеспечивать сохранение высокого уровня для совокупности сущностей. Например, у вас может быть Сохранить (заказ) в слое обслуживания, что приведет к обновлению более базовых объектов, таких как инвентарь, клиент, учетная запись.

...