c# - 创建对可能变化的模式的数据访问

标签 c# .net database orm ado.net

我正在开发的产品需要支持不同的数据库类型。一开始需要支持SQL ServerOracle,以后可能需要支持IBM DB2Postgre SQL .

并且该产品需要适用于架构可能略有不同的不同客户。例如,一个 SQL Server 客户端上的列名可能是 _ID,而在另一个 Oracle 客户端上,它可能是 I_ID.

除列名外,一般架构是相同的。它们都可能被映射到同一个对象。 但是,可能会有一些特定于每个客户的额外列。这些不需要映射到对象。可以使用更简单的方法在 Master-Detail 场景中检索它们。

我想使用 ORM,因为我们需要支持不同类型的数据库提供程序。但据我所知,ORM 不适合在运行时创建映射。

为支持这些请求(摘要):

  1. 每个客户的列名称可能不同,但除了名称之外它们几乎是相同的列。
  2. 每个客户的数据库提供商可能不同。
  3. 每个客户可能有额外的列。
  4. 编辑:程序应该能够通过在运行时更改配置来支持新数据库。

为此类规范创建数据访问的好方法是什么?有没有办法用 ORM 做到这一点?或者我是否需要编写特定于每个数据库的代码来支持这种情况?我是否有任何其他选项比直接使用 ADO.NET 更容易?

编辑:我觉得我的问题写得太笼统了,没有解释清楚,对此深表歉意。问题是我不会创建数据库。它们将已经创建,并且程序应该能够通过在运行时配置程序来使用新数据库。我无法控制数据库。

另外一点,当然可以通过在程序中创建SQL语句来实现,但是那实在是太麻烦了。所有这些提供商的规则和 SQL 实现都略有不同,因此工作量很大。我想知道我是否可以使用 ORM 之类的东西来简化我的工作。

编辑 2: 我完全意识到这是一种愚蠢的做事方式,它表明了错误的设计决策。但我花了很多时间试图说服我的公司不要这样做。他们不想因为实习生这样告诉他们而改变自己的思维方式。因此,我们将不胜感激。

最佳答案

Column names may be different for each customer, but they pretty much the same columns except names.

仅由于这一要求,您就必须自行动态构建 SQL 语句,但这确实非常简单。我建议构建一个这样的表:

CREATE TABLE DataTable (
    ID INT PRIMARY KEY NOT NULL,
    Name SYSNAME NOT NULL
)

将所有表存储在数据库中。然后像这样构建一个:

CREATE TABLE DataTableField (
    ID INT PRIMARY KEY NOT NULL,
    DataTableID INT NOT NULL,
    Name SYSNAME NOT NULL
)

存储字段的基本名称。您只需选择一个架构并将其称为基线。这就是那两个表中的内容。然后你有一个这样的表:

CREATE TABLE Customer (
    ID INT PRIMARY KEY NOT NULL,
    Name VARCHAR(256) NOT NULL
)

存储您使用该产品的所有唯一客户,最后是这样的表格:

CREATE TABLE CustomerDataTableField (
    ID INT PRIMARY KEY NOT NULL,
    CustomerID INT NOT NULL,
    DataTableFieldID INT NOT NULL,
    Name SYSNAME,
    IsCustom BIT
)

为每个客户存储不同的字段名称。我们将在一分钟内讨论 IsCustom

现在您可以利用这些表来动态构建您的 SQL 语句。在 C# 中,您可能会在应用程序首次加载时预先缓存所有这些数据,然后使用这些数据结构来构建 SQL 语句。但是开始吧,如果您对此有具体问题,请创建一个新问题,添加您已有的代码,并让我们知道您在哪里遇到问题。

Database provider may be different for each customer.

在这里你需要使用类似 Dapper 的东西因为它与 POCO 类一起工作(就像你将要构建的那样)并且它也只是扩展了 IDbConnection 接口(interface)所以你使用什么具体类并不重要(例如 SqlConnectionOracleConnection),它的工作原理是一样的。

There may be extra columns for each customer.

这其实很简单。利用 CustomerDataTableField 表中的 IsCustom 字段将这些字段添加到动态构建的 SQL 语句中。这解决了数据库方面的问题。现在,为了解决类方面的问题,我建议您利用 partial 类。所以考虑这样一个类:

public partial class MyTable
{
    public int ID { get; set; }
    public string Field1 { get; set; }
}

代表基线 架构。现在,除标记为 IsCustom 的字段外,所有内容都映射到这些字段中,因此我们需要对这些字段进行一些处理。好吧,让我们为这个类构建一个扩展:

public partial class MyTable
{
    public string Field2 { get; set; }
}

因此,现在当您构建一个 new MyTable() 时,它将始终具有这些附加字段。 但是,您不希望每个客户都这样,对吗?好吧,这就是我们使用 partial 类的原因,您在外部程序集中定义这些 partial 类,只为正确的客户安装。现在您拥有了一系列小型的、客户特定的系统扩展,并且它们很容易开发、安装和维护。

关于c# - 创建对可能变化的模式的数据访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16813271/

相关文章:

c# - 代码约定的条件属性异常

.net - TPL 数据流管道的吞吐量

sql-server - 如何获取所有实例数据库的用户列表

javascript - 从仪器 javascript 脚本中的数据库或文本文件中读取数据

c# - 如何使用 LINQ 中的 Dynamic 处理 Dapper 返回键值对

c# - 如何在 ASP.Net 中根据角色隐藏菜单项

c# - 术语 "context"和 "_context"在 .NET Core 中意味着什么?

.net - 用于 .NET 的轻量级 x86 模拟器/在托管环境中执行 x86 代码

c# - 自托管 Web API 时使用 Ninject InRequestScope()

database - Scala Slick 更新列值