从数据访问层加载对象图的推荐方法是什么?
What's the recommended way to load an object graph from Data Access Layer?
来自一本比较老的软件架构书:
In other situations, the same conceptual Get-Orders query
might generate different data—for example, a collection of Order
objects plus order items information. What should you do? Should you
expose two slightly different GetOrders methods out of your
DAL? And what if, depending on the user interface, the user might ask
the system to return orders, order items, and products by country?
Will you define yet another look-alike method in the DAL?
作者建议使用查询对象模式。我能想到的其他方式:
1) 每个 relation/child 集合的可选参数:
IOrder GetOrder(int id, bool withItems = false);
2) 元组
从 IOrder 定义中删除 IList 并return一个元组
Tuple<IOrder, IList<IOrderItems>> GetOrderWithItems(int id);
3) 方法重载
IOrder GetOrder(int id);
IOrder GetOrderWithItems(int id);
4) 分离方法
DAL 不应该处理这个问题。检索订单及其商品应分两步完成:
IOrder myOder = GetOrder(myOrderId);
myOrder.items = GetOrderItems(myOrderId);
最好的方法是什么?我担心的另一个问题是空引用。当 items = null 时,DAL 客户端可能会将其混淆为 0(订单没有项目)。如何处理?
-公约
null = 不是 loaded/set
空集合 = 0 项
-包装器
ItemsWrapper 为空:项目未加载
ItemsWrapper.items 为 null 或(空):0 项
-泛型(这可能是愚蠢的)
interface IOrder<TVoidableItems> where TVoidableItems : IWithoutItems
{
int id;
TVoidableItems items;
}
interface IWithoutItems{}
interface IWithItems: IWithoutItems { IList<IOrderItems> value;}
如果第二个问题跑题了,请告诉我,我会移到第二个话题。我相信这是相关的。也许我不应该首先为 DAL 使用域对象并使用简单的无关系类型?
作者似乎假设有一条从数据库直接到 UI 的快速通道。
在经典的领域驱动设计中,事情并没有那么简单,至少有领域层,中间可能还有几个其他层。在域模型中,Order
将(可能)有一个 Items
的列表,形成一个聚合,但您会从那里生成额外的 DTO/viewmodels/whatever 以在 [=21] 中获得可显示的内容=].
在 DDD+CQRS 上下文中,读取端的数据库数据和演示就绪数据之间的对应关系更快。我会根据视图调整我的数据结构,这可能意味着两个读取模型:OrderWithItems
和 Order
.
另一方面,作者 (Dino Esposito) 在 his book is the clear separation of concerns that CQRS brings. If I'm not mistaking, this pattern is completely missing from his book. In Esposito's latest MSDN article, he explains CQRS, so I think he just wasn't that experienced at the time of writing that book. Unfortunately, the article still misses some fundamental abstractions that make query objects really powerful. This article 中遗漏的内容更详细地介绍了如何更有效地为您的应用程序建模。
来自一本比较老的软件架构书:
In other situations, the same conceptual Get-Orders query might generate different data—for example, a collection of Order objects plus order items information. What should you do? Should you expose two slightly different GetOrders methods out of your DAL? And what if, depending on the user interface, the user might ask the system to return orders, order items, and products by country? Will you define yet another look-alike method in the DAL?
作者建议使用查询对象模式。我能想到的其他方式:
1) 每个 relation/child 集合的可选参数:
IOrder GetOrder(int id, bool withItems = false);
2) 元组
从 IOrder 定义中删除 IList 并return一个元组
Tuple<IOrder, IList<IOrderItems>> GetOrderWithItems(int id);
3) 方法重载
IOrder GetOrder(int id);
IOrder GetOrderWithItems(int id);
4) 分离方法
DAL 不应该处理这个问题。检索订单及其商品应分两步完成:
IOrder myOder = GetOrder(myOrderId);
myOrder.items = GetOrderItems(myOrderId);
最好的方法是什么?我担心的另一个问题是空引用。当 items = null 时,DAL 客户端可能会将其混淆为 0(订单没有项目)。如何处理?
-公约
null = 不是 loaded/set
空集合 = 0 项
-包装器
ItemsWrapper 为空:项目未加载
ItemsWrapper.items 为 null 或(空):0 项
-泛型(这可能是愚蠢的)
interface IOrder<TVoidableItems> where TVoidableItems : IWithoutItems
{
int id;
TVoidableItems items;
}
interface IWithoutItems{}
interface IWithItems: IWithoutItems { IList<IOrderItems> value;}
如果第二个问题跑题了,请告诉我,我会移到第二个话题。我相信这是相关的。也许我不应该首先为 DAL 使用域对象并使用简单的无关系类型?
作者似乎假设有一条从数据库直接到 UI 的快速通道。
在经典的领域驱动设计中,事情并没有那么简单,至少有领域层,中间可能还有几个其他层。在域模型中,Order
将(可能)有一个 Items
的列表,形成一个聚合,但您会从那里生成额外的 DTO/viewmodels/whatever 以在 [=21] 中获得可显示的内容=].
在 DDD+CQRS 上下文中,读取端的数据库数据和演示就绪数据之间的对应关系更快。我会根据视图调整我的数据结构,这可能意味着两个读取模型:OrderWithItems
和 Order
.
另一方面,作者 (Dino Esposito) 在 his book is the clear separation of concerns that CQRS brings. If I'm not mistaking, this pattern is completely missing from his book. In Esposito's latest MSDN article, he explains CQRS, so I think he just wasn't that experienced at the time of writing that book. Unfortunately, the article still misses some fundamental abstractions that make query objects really powerful. This article 中遗漏的内容更详细地介绍了如何更有效地为您的应用程序建模。