Модель единицы работы и объем транзакции для Linq-To-Sql? - PullRequest
3 голосов
/ 16 декабря 2010

Я хотел бы имитировать подход репозитория, который широко используется в DDD с Linq-2-Sql в моем портальном приложении.Пока у меня есть это:

     public class LinqToSqlDal<DC,T>: IDisposable, IRepository<T> 
        where T: LinqEntity, new(),
        where DC: DataContext, new() 
     {

              private DC unitOfWork = null;

              public LinqToSqlDal(string connectionString) 
              {
                   this.unitOfWork = Activator.CreateInstance(typeof(DC), connectionString) as DC; 
              }

               public LinqToSqlDal(string connectionString, DataLoadOptions loadOptions): this(connectionString) 
              {
                   this.unitOfWork.LoadOptions = loadOptions;
              }

              public virtual void SubmitChanges() { 
                 this.unitOfWork.SubmitChanges();
              }

              public virtual List<T> Get(Expression<Func<T,bool>> query) 
              {
                   return this.unitOfWork.GetTable<T>().Where(query);
              }

              public virtual void Delete(Expression<Funct<T, bool>> query) 
              {
                   this.unitOfWork.GetTable<T>().DeleteAllOnSubmit(this.unitOfWork.GetTable<T>().Where(query));
              }

              public virtual T GetByID<T>(Expression<Funct<T, bool>> query) 
              {
                     return this.unitOfWork.GetTable<T>().Where(query).SingleOrDefault();
              }

              public virtual object Add(T entity, string IDPropertyName) 
              {
                this.unitOfWork.GetTable<T>().InsertOnSubmit(entity);
                this.SubmitChanges();

                 var ID = (string.IsNullOrEmpty(IDPropertyName)) ? null : 
                    entity.GetType().GetProperty(IDPropertyName).GetValue(entity, null);

                   return ID;
              }

               public virtual void SubmitChanges() 
               {
                   this.unitOfWork.SubmitChanges();
               }

              public void Dispose() 
              {
                 this.unitOfWork.Dispose();
              }


     }

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

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

1 Ответ

3 голосов
/ 17 декабря 2010

Я бы определенно создал какой-то централизованный, но управляемый извне контроль транзакций.Лично я предпочитаю UnitOfWork, потому что вы можете сделать его абстрактным, привязанным только к модели репозитория, а не к деталям, связанным с реализацией.

В настоящее время ваша единица работы зависит от реализации.Ваши разработчики знают, что объект с именем unitOfWork на самом деле является DataContext для Linq2SQL.Зная это, они могут полностью обойти Хранилище и использовать UnitOfWork для выполнения своих вызовов БД.Для них было бы плохой идеей сделать это, но тот факт, что они могут сделать это, предполагает необходимость более полной инкапсуляции конкретных деталей за лучшим рефератом.

Я бы сделал UnitOfWork классом токена;маркер является просто абстрактным заполнителем, который ссылается на атомарный набор операций.За кулисами вы можете использовать UnitsOfWork для управления ключами коллекции DataContexts и использовать контекст для определенного UnitOfWork всякий раз, когда этот токен представляется в хранилище вызывающим методом (он будет передан в качестве параметра).Когда UnitOfWork отбрасывается внешним кодом, избавьтесь от DataContext.Подобное проектирование вашего репозитория означает, что использование кода не требует каких-либо знаний о деталях реализации.Если позже вы решите, что Linq2SQL не соответствует вашим потребностям, и вы хотите переключиться на NHibernate, изменения заканчиваются на границе репозитория;Ваш потребительский код не дает мгновенного ответа, ссылается ли UnitOfWork на DataContext или ISession.

...