2

私が取り組んでいる製品は、さまざまなデータベース タイプをサポートする必要があります。最初はSQL ServerOracleをサポートする必要がありますが、将来的にはIBM DB2Postgre SQLをサポートする必要があるかもしれません。

また、製品は、スキーマがわずかに異なるさまざまな顧客に対して機能する必要があります。たとえば、SQL Serverを使用するあるクライアントでは列名が であり、 Oracle_IDを使用する別のクライアントでは列名が.I_ID

一般的なスキーマは、列名を除いて同じです。それらはすべて、潜在的に同じオブジェクトにマップされる可能性があります。ただし、各顧客に固有の追加の列がいくつかある場合があります。ただし、これらをオブジェクトにマップする必要はありません。これらは、より簡単な方法を使用してマスター/ディテールシナリオで取得できます。

さまざまな種類のデータベース プロバイダーをサポートする必要があるため、ORM を使用したかったのです。しかし、私が理解できる限り、ORM は実行時にマッピングを作成するのには適していません。

これらの要求をサポートするには (概要):

  1. 列名は顧客ごとに異なる場合がありますが、名前以外はほとんど同じ列です。
  2. データベース プロバイダーは、お客様ごとに異なる場合があります。
  3. 顧客ごとに追加の列がある場合があります。
  4. 編集:実行時に構成を変更することにより、プログラムは新しいデータベースをサポートできるはずです。

このような仕様のデータ アクセスを作成する良い方法は何ですか? ORMでそれを行う方法はありますか? または、このシナリオをサポートするために、各データベースに固有のコードを記述する必要がありますか? ADO.NET を直接使用するよりも簡単にする他のオプションはありますか?

編集:質問を少し広範に書きすぎたようで、明確に説明していませんでした。申し訳ありません。問題は、データベースを作成しないことです。それらはすでに作成されており、実行時にプログラムを構成することにより、プログラムは新しいデータベースで動作できるはずです。私はデータベースを制御できません。

もう 1 つは、プログラム内で SQL ステートメントを作成することでもちろん可能ですが、それは非常に面倒です。これらのプロバイダーはすべて、わずかに異なるルールと異なる SQL 実装を持っているため、多くの作業が必要です。ORM のようなものを使用して簡単にできるのではないかと考えていました。

編集 2:これはばかげたやり方であり、設計上の決定が悪いことを示していることは十分承知しています。しかし、私は会社にこのようなことをしないよう説得するのに何時間も費やしました. インターンに言われたからといって、考え方を変えたくない。そのため、どんな助けもいただければ幸いです。

4

1 に答える 1

0

列名は顧客ごとに異なる場合がありますが、名前以外はほとんど同じ列です。

この要件だけでも、自分で 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
)

フィールドのベース名を保存します。スキーマを選択して、それをベースラインと呼ぶだけです。それが、これら 2 つのテーブルに表示されます。次に、次のようなテーブルがあります。

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 ステートメントを構築することができます。しかし、それを始めて、それについて具体的な質問がある場合は、新しい質問を作成し、既に持っているコードを追加して、問題が発生している場所をお知らせください.

データベース プロバイダーは、お客様ごとに異なる場合があります。

ここでは、Dapperのようなものを使用する必要があります。これは、POCO クラス (作成するものなど) で動作し、単にインターフェイスを拡張するだけなので、使用する具体的なクラス (または など)IDbConnectionは関係ありません。それは同じように機能します。SqlConnectionOracleConnection

顧客ごとに追加の列がある場合があります。

これは実際には非常に簡単です。IsCustomテーブル内のフィールドを活用してCustomerDataTableField、それらのフィールドを動的に構築された 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これで、システムに対する顧客固有の小さな拡張機能がたくさんあり、それらは簡単に開発、インストール、および保守できます。

于 2013-05-29T12:14:43.000 に答える