我的服务和存储库层的职责

时间:2011-03-10 17:18:12

标签: c# entity-framework entity repository-pattern service-layer

前几天我问了这个问题:

Should the repository layer return data-transfer-objects (DTO)?

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

现在我想出了一个建筑,同时我需要你的意见。我们的想法是,当这样做时,存储库层可以返回我定义的名为IProjectable的接口类型。这包装了查询(存储库层还没有执行查询)但是不允许使用者更改查询(它不是IQueryable),只是为了对它执行投影操作(到目前为止我只是{{ 1}}和First)将执行投影并实际执行查询。

在存储库中是这样的:

ToPagedList

在服务层中就像这样:

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上执行Count()将导致对数据库的额外查询)是定义具有所有这些属性的类型并从存储库层返回它并且不要将其称为“Dto”,这看起来很愚蠢,因为它与DTO相同为了“纯洁”而没有命名相同。这样看来,我可以吃蛋糕,大部分也吃。

我看到的缺点是,您可能会遇到不匹配的问题,即服务层执行的投影实际上无法转换为不应该担心的SQL,或者它执行的位置这种复杂的预测使得哪个层正在进行实际数据访问存在疑问。

如果重要的话,我正在使用Entity Framework 4。

2 个答案:

答案 0 :(得分:0)

  

我是否正确地说这样做   这里的实际数据访问仍然是   存储库层的职责   (因为它应该)和那个   投影到可序列化的形式是   服务的责任   层(应该是)?

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

  

我看到的缺点是你可以得到   服务层所在的不匹配   执行无法预测   实际上它被翻译成了SQL   不应该担心,或   它执行如此复杂的地方   预测使其有问题   什么层正在做实际数据   访问。

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

var users = repository.GetUsers()。FilterByName(&#34; Polity&#34;)。OrderByAge()。ToTransferObjects();

答案 1 :(得分:0)

其中一位开发人员,我最尊重ayende(http://ayende.com/Blog/Default.aspx)说:“ORM是您的存储库”视频 - &gt; http://community.devexpress.com/blogs/seth/archive/2011/03/09/interview-with-ayende-rahien-aka-oren-eini.aspx

问题是你真的需要Repository模式吗? 只是我的意见:))