3

2 つのデータ ストレージにまたがって保存されているビジネス オブジェクトがあります。オブジェクトの一部は Azure Table Storage に格納され、残りの部分は Azure SQL に格納されます。基本的に、SQL 部分はクエリで使用され、Table Storage は多くのスペースを必要とするプロパティに使用されます。

ほとんどの場合、オブジェクトの SQL 部分のみが (SQL クエリで) 使用されます。Table Storage プロパティは、誰かがそのオブジェクトを明示的に要求した場合にのみ必要です。私が達成しようとしているのは、ビジネス オブジェクトの背後に 2 つのデータ ソースがあるという事実を隠し、ストレージ テーブルのプロパティを遅延ロードし (SQL クエリを実行するときには必要ないため)、コードをテスト可能にする設計です。

私の現在の設計には、作業単位によって作成された POCO がいくつかあります。Table Storage 用と SQL 用の 2 つの POCO を作成したくないので、次の設計について考えていました。

//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され、イベントは公開されません。これで、作業単位が を返すとCustomer、SQL プロパティのみが読み込まれ、Get イベントがサブスクライブされます。Customer を使用しているユーザーが残りのプロパティを必要とする場合、イベントがトリガーされ、Table Storage プロパティが読み込まれます。

このデザインについてどう思いますか?それは正しいアプローチですか?これを行うより良い方法を知っていますか?

4

1 に答える 1

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 = "");
}

各オブジェクトのマッピング データを含むデータ レイヤーを使用することもできます (後で例を示します)。

于 2013-02-06T18:18:59.053 に答える