1

私は2部構成のアプリケーションを持っています。1 つの部分は、ホストされた MSSQL データベースを備えたホストされたマシン上で実行される Web アプリケーション (C# 4.0) です。それは素晴らしく、標準的です。もう 1 つの部分は、ネットワーク上でローカルに実行され、メイン データベース (Advantage) と Web データベースの両方にアクセスする Windows アプリケーションです。Web サイトから Advantage データベースにアクセスする方法がありません。

現在、このセットアップは問題なく機能します (ネットワークが機能している場合) が、現在、Web サイトを再構築し、Web フォーム /.NET 2.0 / VB サイトから MVC3 / .NET 4.0 / C# サイトにアップグレード中です。 . 再構築の一環として、内部データベースにすべてのデータがあり、Web データベースにそのサブセットがある新しいテーブルをいくつか追加しています。

内部アプリケーションでは、データベース内のテーブルは、リフレクション フラグと属性フラグを使用してデータを入力するクラスによって表されます。例えば:

[AdvantageTable("warranty")]
public class Warranty : AdvantageTable
{
    [Advantage("id", IsKey = true)]
    public int programID;
    [Advantage("w_cost")]
    public decimal cost;
    [Advantage("w_price")]
    public decimal price;

    public Warranty(int id)
    {
        this.programID = id;
        Initialize();
    }
}

AdvantageTable クラスの Initialize() メソッドは、リフレクションを使用して、すべてのキーとその値に基づいてクエリを作成し、指定されたデータベース列に基づいて各フィールドに入力します。更新も同様に機能します。いずれかのオブジェクトで AdvantageTable.Update() を呼び出し、すべてのデータベース書き込みを処理します。これは非常にうまく機能し、すべての標準 CRUD を非表示にし、新しいテーブルを追加するときに新しいクラスをすばやく作成できるようにします。私たちはそれを変更したくはありませんが、それを必要とする解決策がある場合、それを完全に除外するつもりはありません.

Web データベースにはこのテーブルが必要ですが、コスト データは必要ありません。(ストアド プロシージャ、リフレクション、LINQ-TO-SQL、ADO データ オブジェクトなどを介して) Web データベースに基づく別のクラスを作成することもできますが、保証オブジェクトには同じように動作させたい他の機能がある場合があります。 Web サイトから呼び出されたのか内部アプリから呼び出されたのかに関係なく、2 つのコード セットを維持する必要はありません。たとえば、どの保証が製品に適用されるかを決定する方法のロジックを変更する可能性があります。これを 2 か所ではなく 1 か所で作成してテストする必要があるとします。

私の質問は、このクラスに Advantage データベースや Web データベースからデータを取り込めるようにする良い方法を思いつく人はいますか? 接続文字列だけの問題ではありません。接続文字列には 2 つの非常に異なるアクセス方法があるためです (リフレクションは別としても)。タイプタグをアドバンテージタグに追加[Web("id")]し、Webデータベースに存在するフィールドにのみ配置してその列を指定し、読み取り/書き込みに使用されるロジックのセットを制御する何らかのスイッチを持たせることを検討しましたが、私はそれは苦痛になるだろうと感じています (このメソッドは Web セーフですか? インスタンス化する前にフラグを設定するにはどうすればよいですか?)。だから私には好きなアイデアがなく、私が気づいていない解決策があるのではないかと疑っています。入力はありますか?

4

2 に答える 2

2

基本的な問題は、データ層オブジェクトである保証オブジェクトにビジネス ロジックを配置することだと思います。本当にやりたいことは、両方のデータ ソースがサポートする共通のデータ コントラクト (この場合はインターフェイスである可能性があります) を持ち、どちらのデータ ソースでも操作できる別のクラス/レイヤーにロジックをカプセル化することです。これにより、データの取得方法に関係なく、ビジネス レイヤーで使用できる共通のデータ コントラクトを確立することで、1 つのデータ クラスが 2 つの異なるデータ ソースを操作しようとする問題を回避できます。

したがって、あなたの例では、AdvantageWarranty と WebWarranty があり、どちらも IWarranty を実装している可能性があります。任意の IWarranty で動作して、特定の条件に対して保証がまだ有効かどうかを通知できる別の WarrantyValidator クラスがあります。ちなみに、これは、WarrantyValidator クラスでビジネス ロジックを単体テストする場合に、データをスタブ化するための優れた方法です。

于 2011-05-24T21:45:02.387 に答える
0

私が最終的に思いついた解決策は2つありました。まず、Linq-to-sqlを使用して、各Webテーブルのオブジェクトを生成しました。次に、AdvantageTableからWeb固有のコードを含む新しいクラスを派生させAdvantageWebTable<TABLEOBJECT>、Web固有の属性を追加しました。したがって、クラスは次のようになります。

[AdvantageTable( "保証")]

public class Warranty : AdvantageWebTable<WebObjs.Warranty>
{
    [Advantage("id", IsKey = true)][Web("ID", IsKey = true)]
    public int programID;
    [Advantage("w_cost")][Web("Cost")]
    public decimal cost;
    [Advantage("w_price")][Web("Price")]
    public decimal price;

    public Warranty(int id)
    {
        this.programID = id;
        Initialize();
    }
}

Webデータベースに保存する直前にWebのみのフィールドにデータを入力するためのフックもあり、LoadFromWeb()リフレクションを使用してフィールドにデータを入力する関数があります(ただし、まだ必要ないため、まだありません)。

于 2011-07-08T17:53:43.257 に答える