多数据库数据访问层设计
Design of Data Access Layer with multiple databases
我已经阅读了很多关于拥有多个数据库的问题以及如何在这种情况下有效地设计 DAL 的帖子。在许多情况下,论坛建议应用存储库模式,这在大多数情况下都可以正常工作。
但是,我发现自己处于不同的情况。我有 3 个不同的数据库:Oracle、OLE DB 和 SQLServer。目前,存在一个独特的 DAL,其中包含许多不同的 类 发送 SQL 查询到下面的层以在相应的数据库中执行。该系统的工作方式是其中两个数据库仅用于从中读取信息,另一个数据库用于存储相同的信息或稍后读取。我必须为当前的实现提出一个更好的设计,但从架构的角度来看,所有三个数据库的通用接口似乎不太合理。
有什么设计模式可以解决这种情况吗?我应该拥有三个不同的 DAL 吗?或者也许可以(并且建议)将存储库模式应用于此问题?
您问题的答案可能非常主观。这些是一些想法。
您可以应用命令-查询分离。查询端直接与您的数据层集成,绕过任何业务或领域层,并且返回的实体针对从您的数据库读取和投影进行了优化。该层还可以负责合并来自不同数据库调用的结果。
命令端由命令处理程序组成,使用从您的 R/W 数据库映射的域或业务实体。
这样,你暴露的接口会更清晰,更面向业务。
我不确定是否真的需要使用自定义工作单元和存储库完全抽象出数据访问层:优势是否大于劣势?他们很少这样做,因为你会改变数据库技术吗?如果你这样做了,这可能意味着无论如何都要重写。此外,如果您首先使用 entity framework 代码,那么您已经拥有工作单元和数据库之上的抽象;以及使用 LINQ 的灵活性。
底线——尽量不要over-engineer/over-abstract事情;或者让事情变得超级通用。
您的 core/business 代码永远不应依赖于放置在应用程序 DAL 层中的任何 contract/interface/class。
访问数据是应用程序的 business/core 层需要能够完成的事情,并且它应该能够在不依赖 SQL 语句并且不知道底层数据访问技术。
我认为您需要从应用程序的核心部分删除任何 "sql" 语句。 SQL 依赖于供应商,任何对特定数据库引擎的依赖都需要从您的核心中清除,并移至它所属的 DAL。然后,您需要创建驻留在 DAL 外部的接口,然后为一个或多个 DAL modules/classes 创建实现 类。您的 DAL 可以依赖于您的内核,但反之则不行。
我不明白为什么在这种情况下不能使用存储库层。当我有一个只能读取的数据库时,我通常让存储库接口的名称表明这一点,比如 ICompanyRepositoryRead。
我已经阅读了很多关于拥有多个数据库的问题以及如何在这种情况下有效地设计 DAL 的帖子。在许多情况下,论坛建议应用存储库模式,这在大多数情况下都可以正常工作。
但是,我发现自己处于不同的情况。我有 3 个不同的数据库:Oracle、OLE DB 和 SQLServer。目前,存在一个独特的 DAL,其中包含许多不同的 类 发送 SQL 查询到下面的层以在相应的数据库中执行。该系统的工作方式是其中两个数据库仅用于从中读取信息,另一个数据库用于存储相同的信息或稍后读取。我必须为当前的实现提出一个更好的设计,但从架构的角度来看,所有三个数据库的通用接口似乎不太合理。
有什么设计模式可以解决这种情况吗?我应该拥有三个不同的 DAL 吗?或者也许可以(并且建议)将存储库模式应用于此问题?
您问题的答案可能非常主观。这些是一些想法。
您可以应用命令-查询分离。查询端直接与您的数据层集成,绕过任何业务或领域层,并且返回的实体针对从您的数据库读取和投影进行了优化。该层还可以负责合并来自不同数据库调用的结果。
命令端由命令处理程序组成,使用从您的 R/W 数据库映射的域或业务实体。
这样,你暴露的接口会更清晰,更面向业务。
我不确定是否真的需要使用自定义工作单元和存储库完全抽象出数据访问层:优势是否大于劣势?他们很少这样做,因为你会改变数据库技术吗?如果你这样做了,这可能意味着无论如何都要重写。此外,如果您首先使用 entity framework 代码,那么您已经拥有工作单元和数据库之上的抽象;以及使用 LINQ 的灵活性。
底线——尽量不要over-engineer/over-abstract事情;或者让事情变得超级通用。
您的 core/business 代码永远不应依赖于放置在应用程序 DAL 层中的任何 contract/interface/class。
访问数据是应用程序的 business/core 层需要能够完成的事情,并且它应该能够在不依赖 SQL 语句并且不知道底层数据访问技术。
我认为您需要从应用程序的核心部分删除任何 "sql" 语句。 SQL 依赖于供应商,任何对特定数据库引擎的依赖都需要从您的核心中清除,并移至它所属的 DAL。然后,您需要创建驻留在 DAL 外部的接口,然后为一个或多个 DAL modules/classes 创建实现 类。您的 DAL 可以依赖于您的内核,但反之则不行。
我不明白为什么在这种情况下不能使用存储库层。当我有一个只能读取的数据库时,我通常让存储库接口的名称表明这一点,比如 ICompanyRepositoryRead。