gpt4 book ai didi

c# - 具有延迟加载和多个数据源的 UnitOfWork

转载 作者:行者123 更新时间:2023-11-30 17:55:46 25 4
gpt4 key购买 nike

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

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

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

你觉得这个设计怎么样?这是正确的方法吗?您知道执行此操作的更好方法吗?

最佳答案

可以使用Lazy<T>依赖注入(inject)。请注意,这只是为了给您一些想法。

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

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

关于c# - 具有延迟加载和多个数据源的 UnitOfWork,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14735086/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com