5

別のシステムによって維持されているデータベースで作業しているため、テーブルに大幅な変更を加えることができません。このデータベースのテーブルにはかなりの数のフィールド (30 以上) があり、同じ命名規則、タイプ、または同じ数のフィールドを持つ 2 つのテーブルはありません。これらのテーブルもかなり頻繁に変更され (フィールドの追加、削除、またはタイプの変更)、さらに悪いことに、新しいテーブルも頻繁に作成されます。これで、キューとして使用される、厳密に型指定できるテーブルが 1 つあります。

問題:

テーブル名とそのテーブルのいくつかの列を指定して、テーブルからデータを取得する必要があります。列名は文字列として提供されます。これらのテーブルは頻繁に変更されるため、テーブルごとに厳密に型指定されたエンティティを維持することが難しくなります。

疎結合でありながら、これらのテーブルを操作できるようにクラスを設計するにはどうすればよいでしょうか?

助けてくれてありがとう、私の説明が悪い場合は申し訳ありません。

4

3 に答える 3

1

不安定なデータからどのようなビジネス ロジックを導き出すことができるのか、よくわかりません。私の推測では、レコードに関連付けられたメタデータに対して何らかの作業を行っていると思います。実際のデータではなく、データの集計 (カウント、平均など) を操作します。

私は DataSet を使用し、次のような一般的な SQL ステートメントを使用します。

SELECT * FROM {dynamic table name}
于 2012-11-14T04:14:16.780 に答える
1

1 つのアイデアは、SQL 管理オブジェクト (SMO)テーブルと共に使用して、強力な型を動的に作成することです。

Server srv = new Server(conn);
Database db = srv.Databases["AdventureWorks"];

foreach (Table table in db.Tables)
{
    Console.WriteLine(" " + table.Name);
    foreach (Column col in table.Columns)
    {
        Console.WriteLine("  " + col.Name + " " + col.DataType.Name);
    }
}

この方法でデータ アクセス レイヤーの単体テスト ジェネレーターを作成しました。たとえば、DataTypes 列を使用してクラスを作成できます (より良い実装については、オンラインで C# を参照してください)。

Public Function SQLParameterType(ByVal ParameterDataType As String) As String

    ParameterDataType = ParameterDataType.ToUpper

    If ParameterDataType.IndexOf("NVARCHAR") > 0 Then
        Return "string"
    ElseIf ParameterDataType.IndexOf("VARCHAR") > 0 Then
        Return "string"
    End If

    Select Case ParameterDataType

        Case Is = "BIGINT"
            Return "Int64"
        Case Is = "INT"
            Return "Int32"
        Case Is = "SMALLINT"
            Return "Int16"

        Case Is = "BIT"
            If gIsVBdotNet Then
                Return "boolean"
            Else
                Return "bool"
            End If

        Case Is = "DATETIME"
            Return "DateTime"

        Case Is = "DATETIME2"
            Return "DateTime"

        Case Is = "SMALLDATETIME"
            Return "DateTime"

        Case Is = "MONEY"
            Return "single" 'float
        Case Is = "FLOAT"
            Return "single" 'float
        Case Is = "REAL"
            Return "double"
            'Case Is = "INT"
            '    Return "int32"
            'Case Is = "INT"
            '    Return "int32"
        Case Else
            Return "666"
    End Select

End Function

スキーマに依存しない方法でデータベースに接続するこの単純な ORM を使用すると、動的に生成されたクラスを dB に疎結合できます。.Net 4の新しいDynamic型は、このアプリケーションのポリモーフィック データ型の候補として適しているようです。

于 2012-11-14T04:58:43.157 に答える
0

簡単な修正 (解決策ではありません) は、このようなコード生成ユーティリティを使用して、テンプレートまたはデータタブ スキーマ定義自体に基づいてクラス ファイルを更新/作成することです。少しの作業で、プロジェクトをビルドするときに実行されるカスタム MsBuild タスクを介してプロジェクトでこれを完全に自動化でき、ファイルはソリューション フォルダーに直接更新されます。

しかし、最も重要なことは、テーブル定義が更新されると、ビルド時にコードが壊れてしまうことです。テーブル定義の変更により、どこを修正する必要があるかがわかります。これを機能させるには、こちらで説明されているように、カスタム MsBuild タスクをメイン ビルド タスクの前に実行する必要があります。

このような設計が同様のプロジェクトに利益をもたらすのを見たので、これは間違いなくあなたに利益をもたらし、あなたにとって物事を簡単にします設計が不十分であり、ソリューション データに必要なものの抽象化と分析が不足している可能性が高い原因です。したがって、再構成するために再プログラムする必要があるプログラムを取得します:)しかし、LOBプログラミングの場合、それは珍しいことではありません:)

** 注: 最初の段落で説明した設計を使用することに決めた場合、完全なソリューションを得るには、追加の MsBuild タスクが必要になる場合があります。スキーマの変更。これについてさらに情報が必要な場合は、以下にコメントしてください。

要約すると、F5 キーを押して Visual Studio でソリューションをビルドすると、すべてのクラスがデータベースからの最新の定義で魔法のように更新されます。開発中にモードでReleaseビルドするたびにこれが行われないように、これがビルドでのみ発生するように制約することもできます。Debug

于 2012-11-14T04:44:31.270 に答える