3

前几天我问了这个问题:

存储库层是否应该返回数据传输对象 (DTO)?

答案(只有一个人,但我已经预感到这不是一个好主意)是不,存储库以后不应该处理 DTO 对象(它们的目的纯粹是通过线)和服务层应该处理。

现在我想出了一个结构,同时我需要你的意见。这个想法是,当这样做有意义时,存储库层可以返回我定义的接口类型,称为IProjectable. 这包装了查询(存储库层尚未执行查询)但不允许消费者更改查询(它不是IQueryable),只是为了对其执行投影操作(到目前为止仅对我FirstToPagedList)执行投影并实际执行查询。

所以在存储库中是这样的:

public IProjectable<User> GetUser(int id)
{
  var query = from u in Set<User>()
              where u.UserID == id
              select u;

  return query.AsProjectable();
}

在服务层是这样的:

var dto = repository.GetUser(16).Single(u => new SimpleUserDto
{
  FullName = u.FirstName + " " + u.LastName,
  DisplayAddress = u.Address.Street + u.Address.HouseNumber,
  OrderCount = u.Orders.Count()
});

return dto;

我是否正确地说在这里进行实际数据访问仍然是存储库层的责任(应该是),而对可序列化形式的投影是服务层的责任(应该是)?

我认为有效地做到这一点的唯一另一种方法(User从存储库返回 a并在服务层中Count()对他执行Orders将导致对数据库的额外查询)是定义一个具有所有这些属性的类型并从存储库层,只是不要称它为“Dto”,这看起来很愚蠢,因为它与 DTO 相同,只是为了“纯度”而没有命名相同。这样一来,我似乎也可以大部分时间吃蛋糕了。

我看到的缺点是,您可能会得到一个不匹配的地方,服务层执行的预测实际上无法转换为它不应该担心的 SQL,或者它执行如此复杂的预测,这使得它是什么层是有问题的进行实际的数据访问。

顺便说一句,如果重要的话,我正在使用 Entity Framework 4。

4

2 回答 2

0

我是否正确地说在这里进行实际数据访问仍然是存储库层的责任(应该是),而对可序列化形式的投影是服务层的责任(应该是)?

是的,服务层仍然不知道实际的 DataAccess 是如何执行的(因为它不应该不知道)。调用是否发送到 SQL?中间有缓存层吗?

我看到的缺点是,您可能会得到一个不匹配的地方,服务层执行的预测实际上无法转换为它不应该担心的 SQL,或者它执行如此复杂的预测,这使得它是什么层是有问题的进行实际的数据访问。

对于这个问题,我使用管道模式,它基本上只是 IProjectable 上的一组扩展方法,可以执行经过测试的投影。接下来,在您的 serviceLayer 中,您可以使用这些管道方法的组合来编写查询,例如:

var users = repository.GetUsers().FilterByName("Polity").OrderByAge().ToTransferObjects();

于 2011-03-10T17:36:40.670 回答
0

我最尊敬的开发者之一ayende (http://ayende.com/Blog/Default.aspx) 说:“ORM 是你的存储库”视频在这里-> http://community.devexpress.com/blogs/seth/archive/ 2011/03/09/interview-with-ayende-rahien-aka-oren-eini.aspx

问题是你真的需要存储库模式吗?只是我的观点 :)

于 2011-03-10T18:59:28.757 回答