业务对象和数据访问对象之间的存储库模式和映射

时间:2013-10-31 16:27:00

标签: c# .net entity-framework design-patterns business-logic

我在我的.net MVC项目中使用Entity Framework作为ORM。我已经实现了Repository-Pattern(通用)来获取/保存/更新/删除DAO(数据访问对象)。我还有包含所有业务逻辑的Business Objects。我有 - 例如 - 一个名为Student的DAO和一个名为Student的BO(业务对象)。 BO包含逻辑,DAO只是存储在DB中的数据。 现在我想知道Student-Repository是否应该返回Business-Object而不是DAO? 我可以通过将DAO转换为业务对象,然后从Repository.Get()返回它来使用Automapper实现这一点。与所有其他方法相同。但这是一个好习惯吗?

更新

我有一个数据访问层项目和一个业务逻辑项目。实体框架在部分类(进入数据访问项目)中创建其实体,因此我实际上可以使用其他部分类扩展实体,但问题是我在业务项目中引用了数据访问项目,而我无法访问数据访问项目中的逻辑代码。所以我必须将逻辑放在Business项目中,但由于不可能在两个项目上创建部分类,我必须采用另一种方式...或者您是否知道如何更好地构建和解决问题方式是什么?

2 个答案:

答案 0 :(得分:4)

恕我直言,有几个目标(一些竞争):

  • 使业务逻辑可以单独测试
  • 设计与您的域匹配的域对象
  • 将数据访问与其他所有内容分离
  • 保持简单

您可以在没有数据库的情况下测试业务逻辑吗?可能是的,这些类是EF POCO实体还是从DAO映射。

您的域名对象是否与您的域名匹配?他们的名字是否精心挑选?他们总是处于有效状态吗? (对于一堆公共读/写属性,这可能很困难。)域驱动设计注意事项适用于此处。 (我不是那里的专家。)

您是否可以放弃EF用于Dapper,用于MongoDB的SQL Server或用于Web服务调用的当前数据访问,而无需更改数据访问层之外的任何内容?我的怀疑是否定的。通用存储库往往会将IQueryable泄漏到其他层。并非所有内容都支持查询,提供程序实现也各不相同。单元测试通常使用LINQ to Objects,的行为与LINQ to Entities相同。此外,如果要提取Web服务合同,则必须查看所有类以查找所有查询。请参阅IQueryable is Tight Coupling

最后,你需要所有这些吗?如果您的应用程序的目的是CRUD数据访问,而没有上述简单验证的业务逻辑,则可能不是。这些考虑因素绝对适用于复杂的应用程序或站点。

答案 1 :(得分:1)

是的,这是非常好的做法。通常,您在域程序集中定义了存储库接口。这些接口由域服务使用,并在持久性程序集中实现。实体框架允许您流畅地映射业务实体,而不会使用属性污染它们或强制它们从某些特定的基类(POCO实体)继承。这使您的域模型持久化无知。