使用遗留数据库和Linq to SQL的仓储模式

4
我正在使用一个无法更改的遗留数据库来构建应用程序。我使用Linq to SQL进行数据访问,这意味着我对于每个表都有一个(Linq to SQL)类。
我的领域模型与数据库不匹配。例如,有两个名为“Users”和“Employees”的表,因此我有两个名为“User”和“Employee”的Linq to SQL类。但是在我的领域模型中,我想要一个包含任一表中某些字段的“User”类(但我不关心这些表的许多其他字段)。
我不确定如何设计我的存储库:
  • 存储库是否应执行Linq to SQL类(例如,“User”,“Employee”)到领域类(User)之间的映射,并仅将领域类返回给应用程序
  • 还是我的存储库返回Linq to SQL类,并将映射留给调用者
第一种方法似乎对我来说更有意义,但这是实现我的存储库的正确方法吗?
2个回答

4
纯洁主义者(我试着保持纯洁)认为你的模型代表了你的数据。因此,任何需要持久化的东西都只在需要时通过存储库完成。此外,当你有复杂实体时,你想使用服务来合并它们。例如,User + Employee = UserEmployee实体,只能通过IUserEmployeeService访问。
凭借这些模糊的语句,你有一个很好的机会。
构建一个反腐层,可以让你同时开始迁移遗留数据库。
这是DDD手册中的另一章。反腐化层用于使用Facade、Translator和Adapter与遗留系统进行接口隔离,以便将纯领域模型与遗留数据库隔离开来。
现在,这可能比你想要的工作更多。因此,你现在必须问自己:
你想要开始迁移的过程吗?还是它将在应用程序的整个生命周期内存在?
如果你的答案是可以开始迁移,那么就按照你想要的方式对实际领域进行建模。使用普通存储库和服务进行持久化。快乐地设计你希望存储的方式。然后,使用聚合根的服务进入反腐化层,提取实体,将其存储/更新到本地,并将其转换为你领域中的实体。
如果答案是遗留数据库将在项目的生命周期内存在,那么你的任务就简单得多了。使用你的领域服务(例如UserEmployeeService)进入反腐化的UserFacade和EmployeeFacade(类似于“远程服务”概念)。
在Facades中,使用Adapters(例如LegacyDbSqlDatabase)访问遗留数据库以获取原始legacyUser()。接下来,使用一个UserTranslator()和EmployeeTranslator()映射器,将遗留用户数据转换为你实际领域版本的User()实体,并从UserFacade返回到UserEmployeeService,与从相同位置获取的Employee实体结合。
哇,打字太多了...
有了反腐层的适配器和Facade,你可以做任何你想做的Linq-to-Sql或其他操作。这无关紧要,因为你已经完全将遗留DB/系统与你漂亮纯洁的领域隔离开来——你的领域具有自己的User()和Employee()实体和值对象。

1

DDD 和 Linq To SQL 不太搭配,因为生成的类不适合与您的数据库表结构显著偏离。您将不得不以让使用 Linq to SQL 成为一种痛苦的方式来映射类,或者只能使用非理想的对象模型。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接