Как получить идентификатор, сгенерированный БД после saveChanges, используя DbContextScope - PullRequest
1 голос
/ 20 апреля 2019

Я планирую создать приложение, имеющее следующие слои, и использовать Entity Framework в качестве моего ORM:

  • Презентация : не относится к моему вопросу.
  • Бизнес : в этом слое я планирую использовать только объекты DTO. Я хочу отделить свой бизнес-уровень от деталей реализации базы данных, и поэтому все взаимодействие с объектами осуществляется на уровне DAL.
  • DAL : на этом уровне я планирую иметь весь код Entity Framework и объекты. Я представлю репозитории, которые могут быть вызваны бизнес-уровнем. Эти репозитории ожидают объекты DTO как входные данные и возвращают объекты DTO как выходные данные. Отображение между DTO и сущностью выполняется на этом уровне.

Я просмотрел несколько онлайн-руководств и статей, связанных с Entity Framework, и наткнулся на проект DbContextScope , который выглядит как очень хорошее решение для контроля «бизнес-транзакций» и обеспечения того, чтобы все связанные изменения совершено или отменено. Смотрите GitHub: https://github.com/mehdime/DbContextScope

Демонстрация в этом репозитории GitHub содержит сценарий, когда в базе данных создается новая сущность. Когда я пытаюсь сопоставить этот сценарий со своими слоями, он выглядит так:

  1. Бизнес : создайте DTO со значениями свойств для объекта, который будет сохранен. Создайте новый DbContextScope и репозиторий вызовов на уровне DAL, передавая DTO.

  2. DAL : хранилище сопоставляет DTO с сущностью и добавляет его в DbContext Entity Framework.

  3. Business : вызов метода SaveChanges () для DbContextScope , который, в свою очередь, вызывает SaveChanges () для DbContext Entity Framework.

В демонстрационной версии идентификатор сохраняемой сущности уже известен при создании DTO. Однако я ищу способ определения идентификатора, автоматически назначаемого EF после вызова метода SaveChanges () в DbContextScope на бизнес-уровне. Поскольку на данный момент я нахожусь на бизнес-уровне, у меня больше нет доступа к сущности, поэтому я больше не могу получить свойство идентификатора этой сущности.

Полагаю, я могу определить идентификатор только путем запроса к базе данных только что созданной записи, но это возможно только в том случае, если исходный DTO содержит некоторый уникальный идентификатор, который я мог бы использовать для запроса к базе данных. Но что, если в моем DTO нет уникального значения, которое я могу использовать для запроса?

Любые предложения о том, как решить эту проблему, или вы рекомендуете альтернативный подход к моим слоям? (например, использовать сущности на бизнес-уровне - несмотря на то, что это неправильно)

1 Ответ

0 голосов
/ 21 апреля 2019

Я использую контекстную область Mehdime везде, где могу, так как я обнаружил, что это исключительная реализация единицы работы. Я согласен с комментарием Камило о ненужном разделении. Если EF доверяют служить в качестве вашего DAL, то ему следует доверять, чтобы он работал так, как задумано, чтобы вы могли полностью его использовать.

В моем случае мои контроллеры управляют DbContextScope, и я использую шаблон репозитория в сочетании с дизайном DDD для моих сущностей. Репозиторий служит привратником для взаимодействия с контекстом, находящимся в области видимости и расположенным с помощью DbContextLocator. Когда дело доходит до создания сущностей, хранилище служит фабрикой с методом «Create {X}», где {X} представляет сущность. Это гарантирует, что вся необходимая информация, необходимая для создания объекта, предоставлена, и объект связан с DbContext перед его возвращением, так что объект гарантированно всегда будет в допустимом состоянии. Это означает, что в контексте вызова контекста SaveChanges у ограничивающей службы автоматически появляется объект с назначенным ему идентификатором. ViewModels / DTO - это то, что контроллер возвращает потребителю. У вас также есть возможность вызвать SaveChanges DbContext в пределах границы DbContextScope, которая также покажет идентификаторы до контекста контекста SaveChanges. Это более точный сценарий, когда вы хотите получить идентификатор для слабосвязанных объектов. (Нет связи FK / сопоставлено). Хранилище также обслуживает код «Удалить», чтобы обеспечить управление всеми связанными объектами, правилами и тому подобным. В то время как редактирование сущностей подпадает под методы DDD для самой сущности.

Может быть более пуристический аргумент, что это «пропускает» детали домена или специфические проблемы EF в контроллер, но мое личное мнение заключается в том, что преимущества «доверяющих» сущностей и EF в рамках ограниченного контекста внутри уровень обслуживания далеко, далеко перевешивает все остальное. Это проще и дает вам большую гибкость в вашем коде без необходимости почти дублирующих методов, распространяющихся для предоставления потребителям отфильтрованных данных, или сложной логики фильтрации, чтобы «скрыть» EF от уровня обслуживания. Основное правило, которому я следую, заключается в том, что сущности никогда не возвращаются за пределы их контекста. (Нет отсоединения / повторного присоединения, просто выберите в ViewModels и управляйте созданием / обновлением / удалением объектов на основе переданных в представлении моделей / параметров.)

Если есть более конкретные проблемы / примеры, которые вы можете предоставить, пожалуйста, не стесняйтесь добавлять код, описывающий, где вы видите эти проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...