如何正确封装对具有(几乎)相同架构的不同数据库系统的访问?

Posted

技术标签:

【中文标题】如何正确封装对具有(几乎)相同架构的不同数据库系统的访问?【英文标题】:How to properly encapsulate access to different database systems having (almost) the same schema? 【发布时间】:2016-08-10 07:13:17 【问题描述】:

开始情况:MS SQL 中有一个现有的数据库模式,它与 mysql 中的现有模式完全相同(数据库优先 - 不能因为广泛安装而更改)。但是,它们在用于相应列的数据类型方面可能略有不同。必须通过 C# 访问数据库系统。

问题:如何从应用程序的角度正确封装对两者的访问,即程序员必须不知道他查询的是 MySQL 还是 MSSQL 数据库?

示例:我有一个表,比如 MyTable,主列“Id”为 bigint,列“data”为 varchar。

我的想法是使用 EntityFramework(版本 6)自动生成所有 CRUD 操作。所以我为 MySQL 和 MSSQL 创建了一个 .edmx 模型,我想将其注入逻辑层(即生成的上下文)。但我注意到在 MySQL 的情况下,Id (bigint) 被映射到十进制,而在 MS SQL 中它被映射到 long。现在我想知道这种 EF 方法是否适合,因为两个数据库系统中的相同(命名)列(相同命名表)也有不同的数据类型。出于这个原因,一位同事喜欢自己编写所有语句,就像在旧软件版本中完成的那样,即根本不使用 EF,而只为 MS SQL 和 MySQL 提供由普通 SQL 实现的外观方法。

但是我不喜欢自己写所有的sql语句......

正如我上面提到的,我需要封装数据库访问——但如果不同的数据库系统有不同的映射——如何正确地做到这一点?如果 MSSQL 和 MySQL 映射之间存在任何差异,我可以在 EF 模型前面建立一个外观并实现(数据类型,比如 API)适配器,但这种方法会导致我认为抽象的抽象。

有什么建议吗?

【问题讨论】:

您的意思是希望您的应用程序能够在 SQL Server 和 MySQL 之间切换,以便一个安装使用 MySQL 作为后端,而同一应用的另一个安装使用 SQL Server? 没错!我们有一个必须首先查询的设备数据库。示例:“给我设备 A 的位置”。结果:“服务器 XY 上的 MS SQL 数据库”或“服务器 Z 上的 MySQL 数据库”。然后应用程序必须查询 MS SQL 或 MySQL。两个系统上的模式几乎相同 - 但不是 100%。这就是为什么目前使用普通 sql 的原因。 为带有 EF6 的 SQL Server 和 SQL Compact 执行此操作,但是这两个具有非常相似的数据类型。也许还要检查其他其他 ORM 框架(Hibernate ..)。 【参考方案1】:

对于那些感兴趣的人:我们设法使用了一个上下文,因为两个数据库结构几乎相同。只需将相应的连接字符串传递给 Entites (DbContext) 构造函数。 所以有两种 edmx 模型:一种用于 MySQL,一种用于 MSSQL,而具体的模型类仅在一侧(在我们的例子中为 MSSQL)。

【讨论】:

以上是关于如何正确封装对具有(几乎)相同架构的不同数据库系统的访问?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Auto Layout 创建具有多个不同自定义单元格的 UITableView 具有几乎相同的子视图

微服务架构中,二次浅封装实践

如果我有 2 个具有相同视图但逻辑不同的 Angular 组件,如何正确构建代码?

如何使用 dask/fastparquet 从多个目录中读取多个 parquet 文件(具有相同架构)

如何正确使用线程特定的数据

访问具有相同架构的多个数据库