2016-12-12 13 views
0

Я проектирую свои хранилища, и у меня есть сомнения. Например, при создании нового пользователя я должен добавлять записи в разные таблицы. Сейчас я использую что-то вроде:Должны ли хранилища быть атомарными?

public User CreateNewUser() 
{ 
    try 
    { 
     using (var con = new SqlConnection(_SecureConnectionString)) 
     { 
      con.Open(); 

      using (var transaction = con.BeginTransaction()) 
      { 
       User user = //User Repository query to INSERT the user on dbo.Users and return object 

       user.Items = // Item Repository query to INSERT on dbo.Items that have a FK to dbo.Users 
       user.Whatever = // Whatever repository call to INSERT on tables that are related to the new user 

       transaction.Commit(); 
      } 
     } 
    catch (Exception ex) 
    { 
     transaction.Rollback(); 
     throw; 
    } 
} 

Мой вопрос, если создание нового пользователя, и всегда должны создавать записи на разных таблицах, управляемых другими хранилищами, я должен избегать так атомное и сделать это на один запрос в UserRepository, даже если он вставляется в другие таблицы? Я делаю 3 обращения к базе данных, когда могу сделать это на одном.

+1

Есть ли причина, по которой вы не используете сущность framework? – Fran

+0

Как прокомментировал Зоран, это часть решения игрового сервера, инфраструктура Entity слаба по скорости по сравнению с dapper. Для этого конкретного случая (создания пользователя при регистрации) мне не нужно быть быстрым, но это не всегда так. – Nauzet

+0

Вам не хватает единицы работы, которая будет координировать транзакцию между репозиториями. – plalx

ответ

0

Если вы полагаетесь на EF DbContext в качестве репозитория, то мой ответ на вопрос - да, вы должны использовать DbContext для ввода всех новых объектов. Таким образом, контекст будет контролировать транзакцию базы данных, и все INSERT будут выполняться в рамках одной транзакции при сохранении изменений.

И, как вы уже заметили, это приводит к небольшому осложнению. Некоторые объекты будут существовать в более чем одном DbContext, если только вы не строите один гигантский контекст для всей схемы или базы данных.

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

Другой подход, который я использую очень часто в последнее время, заключается в применении методов DDD и организации ваших объектов в четко определенные группы с указанием агрегатов. В этом случае один объект появится в одном контексте. Но в некоторых операциях вам придется использовать несколько контекстов. Это также потребует, чтобы вы делились связью и транзакцией между контекстами, что в совокупности добавляет много сложности решению.

+0

Спасибо за ваш ответ! Я работаю над игровым сервером, встроенным в .Net Core (поэтому у меня нет TransactionScope ... пока;)), я решил пойти на dapper из-за производительности скорости запроса. Я не уверен, может ли dapper делать такие контексты, как EF. – Nauzet

+0

Нет, с Dapper вы бы создали свои собственные репозитории. Это упрощает использование одних и тех же объектов в нескольких хранилищах, так как вы несете ответственность за то, как вы их сохраняете. –