【问题标题】:UnitOfWork with lazy loading and multiple data source具有延迟加载和多个数据源的 UnitOfWork
【发布时间】:2013-01-22 00:09:06
【问题描述】:

我有跨两个数据存储存储的业务对象。对象的一部分存储在 Azure 表存储中,另一部分存储在 Azure SQL 中。基本上 SQL 部分用于查询,而 Table Storage 用于占用大量空间的属性。

大多数时候,只使用对象的 SQL 部分(在 SQL 查询中)。仅当有人明确要求该对象时才需要表存储属性。我想要实现的设计将隐藏业务对象背后有两个数据源这一事实,延迟加载存储表属性(因为在执行 SQL 查询时不需要它们)并且仍然使代码可测试。

我当前的设计有一些由工作单元创建的 POCO。我不想创建两个 POCO,一个用于 Table Storage,一个用于 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,并且不会公开事件。现在,当工作单元返回Customer 时,它将仅加载 SQL 属性并订阅 Get 事件。如果使用 Customer 的人需要其余属性,则会触发该事件并加载表存储属性。

你觉得这个设计怎么样?这是正确的方法吗?你知道更好的方法吗?

【问题讨论】:

    标签: c# asp.net-mvc azure-sql-database azure-storage


    【解决方案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 = "");
    }
    

    您也可以只使用一个数据层来为每个对象映射数据(我稍后会提供示例)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-01
      • 2018-03-30
      • 2018-12-15
      • 2011-02-22
      • 1970-01-01
      • 2016-02-05
      • 1970-01-01
      相关资源
      最近更新 更多