4

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

我的域模型与数据库不匹配。例如,有两个名为Usersand的表Employees,因此我有两个名为Userand的 Linq to SQL 类Employee。但是在我的域模型中,我希望有一个User类应该包含任一表中的一些字段(但我不关心这些表的许多其他字段)。

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

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

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

4

2 回答 2

4

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

有了这些模糊的陈述,你在这里就有了绝佳的机会。

构建一个反腐败层,它允许您同时开始脱离遗留数据库。

这是 DDD 剧本中的另一章。Anti-Corruption 层用于与使用 Facades、Translators 和 Adapters 的遗留系统接口,以将遗留 DB 与纯域模型隔离。

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

我是要开始移除这个遗留数据库的过程,还是会在应用程序的整个生命周期内保留它?

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

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

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

哇,打字好累啊……

使用您的反腐败层的适配器和外观,您可以执行 Linq-to-Sql 或任何您想做的事情。没关系,因为您已经将遗留数据库/系统与您的漂亮和纯域完全隔离 - 您的域具有自己的 User() 和 Employee() 实体和值对象版本。

于 2009-10-28T22:35:42.640 回答
1

DDD 和 Linq To SQL 不能很好地结合在一起,因为生成的类不会显着偏离您的 DB 表结构。您必须以一种使使用 Linq to SQL 变得痛苦的方式映射您的类,或者只使用非理想的对象模型。

如果您真的想利用 DDD 和存储库模式,请选择 Entity Framework 甚至更好的 NHibernate。

于 2009-10-28T21:10:27.130 回答