实体框架 - 什么是服务层在存储库模式中的角色

时间:2016-05-07 04:00:47

标签: entity-framework

目前,我正在使用具有存储库模式的EF5开发ASP MVC4项目。 我刚加入这个项目。

在这个项目中,我们实现了许多存储库类,这些存储库将负责使用dbcontext进行搜索,更新,删除等,它们也返回DTO类,而在服务层我们使用这些存储库来获取然后DTO转换为视图模型。

每次我想对实体做一些逻辑时,我都会去存储库并在这里编写代码。所以我想知道为什么我们需要服务层和存储库同时,我们可以直接在服务层编写逻辑代码或直接在控制器中使用存储库。

我没有看到任何优势,因为我们的源代码太复杂,我们需要这么多的类(DTO,viewmodel ......),我认为与直接使用存储库或服务相比,性能不佳。

你能在这里指出钥匙吗?谢谢。

1 个答案:

答案 0 :(得分:4)

这很简单:

  • 存储库用于数据访问
  • 服务是针对业务逻辑的

但是,一旦你开始将商业概念灌输到存储库中,就很难扭转局面。

业务概念与数据访问问题相互关联的简单示例是软删除。假设有一个表journal_voucher,从中永远不会删除行,只能将其禁用。因此,如果一行不在记录中,则有一个布尔(位)字段IsActive设置为false

现在,在Delete中使用JournalRepository方法设置IsActive标志而不是删除实体似乎是显而易见的。同样,任何检索方法都可以自动过滤掉非活动记录。

错误。活跃或不活跃是一种商业概念。对于数据访问层,任何数据库字段的内容都是无意义的。它只应该正确地读取和写入。

现在看看会发生什么:其他实体可能只是被硬删除。也许其他人永远不会被删除,或者,为什么不,永远不会被删除。如果一个存储库具有此活动/非活动责任,则下一个明显的步骤是在适当的存储库中实现这些其他CRUD规则。然后出现了一个业务需求,只有当年的记录很有意思......哦,我们必须检查journal_voucher是否甚至可以被停用......依此类推。

您最终得到了许多非常不同的存储库类和分散的业务逻辑。

我相信 if 你决定在Entity Framework的存储库(DbSet s)之上使用你自己的存储库,它们应该是generic repositories。那就是:对于每个实体类,它们完全相同。它们是否应该返回DTO而不是EF实体对象甚至是有争议的(我会投票给后者)。

其他一切都在服务中完成。因此,可能会有JournalService通过正确检查来停用journal_voucher。该服务决定IsActive设置为false,并指示存储库更新实体。 (事实上​​,一个工作单元应该这样做,但这是一个不同的故事)。

这种区别有许多好处:

  • 世界其他地方只与服务沟通。
  • 因此,存储库可以安全地返回IQueryable。这些服务限制了检索数据的数量。
  • 更容易确定涉及多个实体的业务逻辑所在的位置(即几乎所有业务逻辑)。
  • 依赖注入更容易。
  • 可以相对轻松地模拟存储库,并且可以轻松地对服务进行单元测试,而无需在模拟存储库中复制业务规则。