我正在遗留数据库(我无法更改)之上构建应用程序。我正在使用Linq to SQL进行数据访问,这意味着每个表都有一个(Linq to SQL)类。
我的域模型与数据库不匹配。例如,有两个名为Users
和Employees
的表,因此我有两个名为User
和Employee
的Linq to SQL类。但是在我的域模型中,我想要一个User
类,它应该包含来自任何一个表的一些字段(但我不关心这些表的许多其他字段)。
我不确定应该如何设计我的存储库:
User
,Employee
)到域类(User
)之间的映射,并且只将域类返回给应用程序第一种方法对我来说似乎更有意义,但这是实现我的存储库的正确方法吗?
答案 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。