由于我无法控制的原因,我无法使用真正的ORM,因此我不得不创建一个位于原始数据上的自定义DAL,并向消费者返回“域对象”。此外,由于我无法控制的原因,我必须使用存储过程进行数据访问。我应该如何处理用手卷DAL创建复合实体?
我的基本理论,利用该Factory
和Repository
模式进行数据访问的,或至少:
- 到的SqlCommand和朋友的调用由库类,它的参数根据需要和收益隐藏域对象。
- 要创建域对象,存储库具有对其自己类型的工厂(例如客户,订单等)的内部引用。工厂有一个方法,
Create
,它将DataRow作为输入,并将DataRow的列映射到域对象的属性。
这似乎适用于映射到单个表的基本对象。现在,我遇到了以下问题:我希望这些域对象中的一些更丰富,并且有相关对象的集合。下面是这个系统我工作的域对象的一个具体的例子:
class Case
{
public string CaseNumber { get; internal set; }
public ICollection<Message> Messages { get; set; }
}
class Message
{
public int MessageId { get; internal set; }
public string Content { get; set; }
}
简单的说法,Case has many Messages
。我关心的是检索案例的原始数据的最佳方法,因为我还需要一个关联消息列表。在我看来,我可以:
- 运行在CaseRepository第二个存储过程时,我检索一个案例拿到属于它的所有信息 - 这似乎不是一个好主意,因为这意味着每当我查找一个案例时,我正在做两个数据库调用而不是一个。
- 使用一个存储过程返回两个表(其中一个包含带有Case的信息的单个行,一个包含具有属于它的消息的零个或多个行)并调用两个工厂方法,即CaseFactory.Create(caseDataRow)和a循环调用MessageFactory.Create(messageDataRow)。这样做更有意义,因为Case是聚合根(或者假装是根据具体情况而定),所以应该知道如何创建挂在它上面的消息。
第二个选择似乎更好的性能,但更多的代码。有没有第三种选择,我忽略或#2是处理这种复合对象的最佳方式,当我不能使用真正的ORM(甚至像Linq到SQL)
嗯,我从来没有完全得到信息库和TDG之间的区别;我见过的每个演示使用的存储库基本上都是我在这里使用的,你说的更像是一个网关。 –
我使用的NHibernate不支持sprocs返回多个结果集,所以我尝试将对象层次结构压扁成单行。这适用于1-1关系,1-many需要额外的电话。如果您的自定义DAL可以处理返回多个结果集的sprocs,那么这是一个很好的perf win :) – MattDavey
teminology有点模糊 - “存储库”非常模糊。就我个人而言,我使用表格网关来返回DTO和储存库来协调表格网关并将DTO组装到领域模型中。 – MattDavey