2013-02-06 3 views
3

두 데이터 저장소에 걸쳐 저장되는 비즈니스 개체가 있습니다. 개체의 일부는 Azure 테이블 저장소에 저장되고 다른 부분은 Azure SQL에 저장됩니다. 기본적으로 SQL 부분은 쿼리에 사용되는 반면 테이블 저장소는 많은 공간을 차지하는 속성에 사용됩니다.단위 로딩 및 다중 데이터 소스가있는 UnitOfWork

대부분의 경우 SQL 쿼리에서 개체의 SQL 부분 만 사용됩니다. 테이블 저장소 속성은 누군가가 명시 적으로 해당 개체를 요청할 때만 필요합니다. 내가 성취하고자하는 것은 비즈니스 객체 뒤에 두 개의 데이터 소스가 있다는 사실을 숨기고 저장소 테이블 속성을 지연로드하고 (SQL 쿼리를 수행 할 때 필요하지 않기 때문에) 코드를 테스트 할 수있게 만드는 디자인입니다.

현재의 디자인에는 작업 단위에 의해 생성 된 일부 POCO가 있습니다. 나는 두 포항 강판, 표 저장 용 및 SQL에 대한 하나를 만들려하지 않는, 그래서 나는 다음과 같은 설계에 대해 생각했다 :

//Make the properties virtual 
public class Customer 
{ 
    public virtual string Name {get;set;} //Stored in SQL 
    public virtual string Age {get;set;} //Stored in SQL 
    public virtual string Details {get;set;} // This prop is stored in Table Storage 
} 

//Create a derived internal POCO that can notify when a property is asked 
internal class CustomerWithMultipleStorage 
{ 
    public event EventHandler OnDetailsGet; 

    public override string Details 
    { 
     get { if (OnDetailsGet!=null) OnDetailsGet(...); /* rest of the code */ } 
     set { /* code */ } 
    } 
} 

내 모든 데이터 계층 코드가 CustomerWithMultipleStorage와 함께 작동하지만 모든 "외부" DL 외부의 코드는 Customer을 사용하며 이벤트는 노출되지 않습니다. 이제 작업 단위 (UOW)가 Customer을 리턴하면 SQL 특성 만로드하고 Get 이벤트를 등록합니다. 고객을 사용하는 다른 사용자가 나머지 속성을 필요로하는 경우 이벤트가 트리거되고 테이블 저장소 속성이로드됩니다.

이 디자인에 대해 어떻게 생각하십니까? 올바른 접근 방법입니까? 이 일을하는 더 좋은 방법을 알고 있습니까?

답변

1

Lazy<T> 의존성 주입과 함께 사용하십시오. 이것은 당신에게 몇 가지 아이디어를주는 것입니다.

internal class CustomerWithMultipleStorage : Customer 
{ 
    private readonly ISqlDataLayer _sqlDataLayer; 
    private readonly ITableStorageDataLayer _tableStorageDataLayer; 
    private readonly Lazy<string> _details; 
    private string _detailsValue; 

    public CustomerWithMultipleStorage(ISqlDataLayer sqlDataLayer, ITableStorageDataLayer tableStorageDataLayer) 
    { 
     _sqlDataLayer = sqlDataLayer; 
     _tableStorageDataLayer = tableStorageDataLayer; 

     _details = new Lazy<string>(() => return (string)_tableStorageDataLayer.GetValue<Customer>(this, "Details")); 
    } 

    public override string Details 
    { 
     get 
     { 
      return (_detailsValue ?? (_detailsValue = _details.Value)); 
     } 
     set 
     { 
      _detailsValue = value; 
      _tableStorageDataLayer.SetValue<Customer>(this, _detailsValue); 
     } 
    } 
} 

public interface ITableStorageDataLayer 
{ 
    object GetValue<T>(T item, [CallerMemberName] string property = ""); 
    void SetValue<T>(T item, object value, [CallerMemberName] string property = ""); 
} 

각 개체에 대한 매핑 데이터가있는 데이터 레이어를 사용할 수도 있습니다 (나중에 예제를 제공합니다).

관련 문제