存储库模式与遗留数据库和Linq to SQL

时间:2009-10-28 20:32:21

标签: linq-to-sql domain-driven-design ddd-repositories

我正在遗留数据库(我无法更改)之上构建应用程序。我正在使用Linq to SQL进行数据访问,这意味着每个表都有一个(Linq to SQL)类。

我的域模型与数据库不匹配。例如,有两个名为UsersEmployees的表,因此我有两个名为UserEmployee的Linq to SQL类。但是在我的域模型中,我想要一个User类,它应该包含来自任何一个表的一些字段(但我不关心这些表的许多其他字段)。

我不确定应该如何设计我的存储库:

  • 如果存储库执行Linq到SQL类(例如UserEmployee)到域类(User)之间的映射,并且只将域类返回给应用程序
  • 或者我的存储库是否应该将Linq返回给SQL类并将映射保留给调用者

第一种方法对我来说似乎更有意义,但这是实现我的存储库的正确方法吗?

2 个答案:

答案 0 :(得分:4)

纯粹主义者(我试着保持纯洁)会告诉你,你的模型代表你的数据。因此,只有在通过存储库需要时才需要持久保存。此外,当您有复杂的实体时,您希望使用服务来组合它们。例如,User + Employee = UserEmployee实体只能通过IUserEmployeeService访问。

通过这些模糊的陈述,你在这里有一个很好的机会。

构建反腐败层,允许您同时开始离开旧版数据库。

这是DDD剧本的另一章。 Anti-Corruption层用于使用Facade,Translators和Adapters与旧系统连接,以将旧版DB与纯域模型隔离。

现在,这可能比你想要的工作多得多。所以,你现在必须问自己:

  

我想开始这个过程吗?   离开这个遗留数据库,或将   它仍然是生命的   应用

如果您的答案是,您可以开始迁移,然后按照您希望的方式为您的实际域建模。使用正常的存储库和服务保留它。以您希望存储的方式设计它。然后,使用聚合根的服务进入反腐败层并提取实体,在本地存储/更新它们,并转换为您域的实体。

如果答案是遗留数据库将在项目的整个生命周期内保留,那么您的任务就容易多了。使用您的域名服务(例如UserEmployeeService)进入反腐败的UserFacade和EmployeeFacade(类似于“远程服务”概念)。

在Facades中,使用适配器(例如LegacyDbSqlDatabase)访问旧数据库以获取原始legacyUser()。下一步是使用UserTranslator()和EmployeeTranslator()映射器将旧版用户数据转换为实际域的User()实体版本,并将其从UserFacade返回到UserEmployeeService,并与之结合使用。来自同一地方的员工实体。

哇,那是很多打字......

使用Anti-Corruption层的适配器和外墙,您可以执行Linq-to-Sql或任何您想要执行的操作。这并不重要,因为您完全将遗留的数据库/系统与您的良好和纯域隔离开来 - 您的域具有自己的User()版本和Employee()实体和值对象。

答案 1 :(得分:1)

DDD和Linq To SQL不能很好地结合在一起,因为生成的类并不意味着与数据库表结构有很大差异。您必须以一种方式映射您的类,使得使用Linq to SQL变得很痛苦,或者只是使用非理想的对象模型。

如果你真的想利用DDD和存储库模式去实体框架甚至更好的NHibernate。