2010-12-16 3 views
3

포털 앱에서 Linq-2-Sql과 함께 DDD에서 널리 사용되는 저장소 접근 방식을 모방하고 싶습니다.Linq-To-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(); 
       } 


    } 

그래서 지금은 개체가 속한 엔터티와의 DataContext에 이것을 사용할 수 있습니다 : 지금까지 나는이 있습니다. 내 질문은 -이 작은 저장소 혜택 내에서 TransactionScope를 전달하거나 인스턴스화하는 것이겠습니까? 지금까지 단 하나의 DataContext가 있지만 여러 개의 데이터 컨텍스트에서 트랜잭션을 보장하기 위해 현재 디자인을 수행 할 수있는 여러 가지 작업을 진행할 수 있습니까?

제네릭을 사용하여 컨텍스트를 래핑하고 클라이언트가 처분하도록하는 것이 좋은 방법입니까?

답변

3

필자는 일종의 중앙 집중식이지만 외부 제어되는 트랜잭션 제어를 확실히 만들 것입니다. 개인적으로 UnitOfWork를 선호합니다. 이는 구현 특정 세부 사항이 아닌 리포지토리 모델에만 연결되는 추상으로 디자인 할 수 있기 때문입니다.

현재 작업 단위 (UOW)는 구현에 따라 다릅니다. 개발자는 unitOfWork라는 이름의 객체가 실제로 Linq2SQL의 DataContext라는 것을 알고 있습니다. 이를 알고 있으면 저장소를 완전히 무시하고 UnitOfWork를 사용하여 DB 호출을 할 수 있습니다. 그들이 그렇게하는 것은 나쁜 생각 일 수 있지만 더 추상적 인 배경에 특정 세부 사항을보다 완벽하게 캡슐화해야 할 필요성을 제시 할 수 있다는 사실입니다.

저는 UnitOfWork를 토큰 클래스로 만듭니다. 토큰은 단순히 조작의 원자 세트를 참조하는 추상 자리 표시 자일뿐입니다. 뒤에서 UnitsOfWork를 사용하여 DataContext 컬렉션을 키 조작하고 해당 토큰이 호출 메소드 (이는 매개 변수로 전달 됨)를 통해 저장소에 제공 될 때마다 특정 UnitOfWork에 대한 컨텍스트를 사용할 수 있습니다. UnitOfWork가 외부 코드에 의해 삭제되면 DataContext를 삭제합니다. 이처럼 리포지토리를 디자인하면 소비 코드가 구현 세부 정보를 전혀 알 필요가 없습니다. 나중에 Linq2SQL이 당신의 필요를 충족시키지 못하고 당신이 NHibernate로 전환하기를 원한다면 변경 사항은 Repository 경계에서 끝납니다; UnitOfWork가 DataContext 또는 ISession을 참조하는지 여부에 관계없이 소비 코드는 플립 플립을주지 않습니다.

+1

좋은 의견, 나중에 다른 구현으로 변경할 수 있도록 DataContext의 특정 구현을 추상화하는 방법에 대한 의사 코드를 제공 할 수 있습니까? – dexter