目前,我正在使用具有存储库模式的EF5开发ASP MVC4项目。 我刚加入这个项目。
在这个项目中,我们实现了许多存储库类,这些存储库将负责使用dbcontext
进行搜索,更新,删除等,它们也返回DTO类,而在服务层我们使用这些存储库来获取然后DTO转换为视图模型。
每次我想对实体做一些逻辑时,我都会去存储库并在这里编写代码。所以我想知道为什么我们需要服务层和存储库同时,我们可以直接在服务层编写逻辑代码或直接在控制器中使用存储库。
我没有看到任何优势,因为我们的源代码太复杂,我们需要这么多的类(DTO,viewmodel ......),我认为与直接使用存储库或服务相比,性能不佳。
你能在这里指出钥匙吗?谢谢。
答案 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
。这些服务限制了检索数据的数量。