我应该如何处理带有手动DAL的复合实体的创建?

由于无法控制的原因,我无法使用真正的ORM,因此我不得不创建一个自定义DAL,该DAL位于原始数据之上,并将“域对象”返回给使用者.另外,出于无法控制的原因,我必须使用存储过程进行数据访问.

我正在使用Factory和Repository模式进行数据访问,或者至少在基本理论上:

>对SqlCommand和朋友的调用被Repository类隐藏,该类根据需要获取参数并返回域对象.
>要创建域对象,存储库必须内部引用其自身类型(例如客户,订单等)的工厂.工厂只有一个方法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有许多消息.我关心的是检索Case原始数据的最佳方法,因为我还需要关联消息的列表.在我看来,我可以:

>当我检索一个Case以获取所有属于它的消息时,在CaseRepository中运行第二个存储过程-这似乎不是一个好主意,因为这意味着每次我查找一个Case时,我都会创建两个数据库呼叫而不是一个.
>使用一个存储过程返回两个表(一个表包含一行包含Case信息的表,一个表包含零行或更多行并包含属于该表的消息),并调用两个工厂方法,即CaseFactory.Create(caseDataRow)和一个循环调用MessageFactory.Create(messageDataRow).因为Case是聚合根(或视情况假装成一个),所以这更有意义,因此应该知道如何创建与其挂起的消息.

第二种选择似乎性能更好,但代码更多.当我无法使用真正的ORM(甚至连Linq to SQL之类的东西)时,是否还有我忽略的第三个选择还是#2处理此类复合对象的最佳方法?

最佳答案
就目前而言,您的存储库更像是表网关(甚至通过sproc).您将需要一个新的存储库层,该存储库可以访问一个或多个表网关,并且能够根据许多表返回的数据来组合复合域实体.

class Customer
{
    string name; // etc
    Address homeAddress;
    Order[] orders;
}

interface ICustomerTableGateway { ... }

interface IAddressTableGateway { ... }

interface IOrderTableGateway { ... }

class CustomerRepository
{
    Customer Get(int id)
    {
        customer = customerTableGateway.Get(id);
        customer.Address = addressTableGateway.Get(customer.id);
        customer.Orders = orderTableGateway.GetAll(customer.id);
    }
}

如果您可以从单个sproc返回多个表,那将进一步简化事情:)

转载注明原文:我应该如何处理带有手动DAL的复合实体的创建? - 代码日志