我应该如何处理带有手动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返回多个表,那将进一步简化事情:)
标签:data-access,data-access-layer,c 来源: https://codeday.me/bug/20191202/2087004.html