2

私たちは、レガシー システムを .NET に移植する作業を進めています。これは、アーキテクチャをクリーンアップするためだけでなく、レガシー システムでは簡単に実現できない多くの新しい可能性を利用するためでもあります。

注: 投稿する前に投稿を読んでいると、所々で説明が少し速すぎた可能性があることに気付きました。詳細については説明しません。不明な点がある場合は、コメントを残してください(回答ではありません)。可能な限り補足します

レガシー システムはデータベースを使用し、100% カスタムで記述された SQL が随所に使用されています。データを必要とするコードはジョブに必要なもののみを取得するため、これによりテーブルが広くなります (つまり、列が多くなります)。

移植の一環として、カスタム SQL に加えて、使用できる ORM レイヤーを導入しました。私たちが選択した ORM は DevExpress XPO であり、この機能の 1 つがいくつかの問題を引き起こしました。つまり、たとえば Employee テーブルの ORM クラスを定義するときに、すべての列のプロパティを追加する必要があるということです。そうしないと、それらを取得できません。

これはまた、従業員を取得すると、少数の列しか必要としない場合でも、すべての列を取得することを意味します。

ORM を使用する利点の 1 つは、プロパティ関連のロジックを同じクラスに配置できることです。たとえば、姓、名、ミドルネームを組み合わせて「表示名」にする簡単な表現は、例としてそこに置くことができます。

ただし、どこかに SQL コードを記述した場合は、DAL のような構造で、またはどこでも、この式を複製する必要があります。これは間違っているように感じられ、バグとメンテナンスの悪夢のレシピのように見えます。

ただし、次の 2 つの選択肢があります。

  • ORM、すべてをフェッチ、一度ロジックを記述可能
  • SQL、必要なものを取得、ロジックを複製する必要がある

次に、代替案を考え出しました。ORM オブジェクトは辞書からコード生成されるため、一連のダム クラスも生成することにしました。これらは同じ数のプロパティを持ちますが、同じ方法で ORM に関連付けられません。さらに、生成されたすべてのオブジェクトにインターフェースを追加し、ORM オブジェクトとダム オブジェクトの両方にこのインターフェースを実装させました。

これにより、このロジックの一部をインターフェイスに関連付けられた拡張メソッドに移動することができました。ダム オブジェクトは、SQL クラスにプラグインするのに十分な情報を持っているため、DataTable を取得する代わりに、利用可能なロジックを使用して List を取得できるため、これは機能しているように見えます。

ただし、これにより別の問題が発生しました。従業員が誰であるか (つまり、システム内の識別子) と名前 (ファースト、ミドル、ラスト) を知る必要があるコンテキストでのみ従業員を表示または処理するコードを書きたい場合、私はこのダム オブジェクトを使用します。私を呼び出すコードが実際にこれらすべてのものを提供していることをコンパイラが保証することはありません。

1 つの解決策は、どのプロパティに値が割り当てられているかをオブジェクトに認識させることです。割り当てられていないプロパティを読み取ろうとすると、例外が発生してクラッシュします。これにより、コードが十分な情報を渡していない場合に、実行時に契約違反を検出する機会が得られます。

これも私たちには不格好に見えます。

だから基本的に私がアドバイスしたいのは、他の誰かがこの状況にあったか、そうであるか、そしてあなたが与えることができるヒントやアドバイスです.

現時点では、テーブルを分割することはできません。レガシ アプリケーションは、ポートのサイズのために何年も存在する必要があり、.NET コードは 3 年以内にリリースされるタイプのプロジェクトではありませんが、途中のリリースで段階的に導入されます。そのため、レガシー システムと .NET コードの両方が同じテーブルを操作する必要があります。

また、これが理想的な解決策ではないことも承知していますので、「このようにするべきではなかった」などのアドバイスはご遠慮ください。私たちはこれをよく知っています:)


私たちが調査したことの 1 つは、"コントラクト" を使用して XML ファイルなどを作成することです。したがって、この XML ファイルに次のようなものを入れることができます。

  • これらの 50 個のプロパティを持つ Employee クラスがあります
  • さらに、プログラムのさまざまな部分に、これらの 7 つのバリエーションがあります。
  • さらに、これらの 10 個のロジックがあり、それぞれがプロパティ X、Y、および Z を必要とします (X、Y、および Z はこれらの 10 の間で異なります)。

これにより、これらの 8 つのクラス (完全なクラス + 7 つの小さなバリエーション) をコード生成し、バリエーション #3 にプロパティ X、Y、および K が存在することをジェネレーターに検出させることができます。ロジックまたはロジックが必要とするインターフェースをこのクラスに自動的に追加します。これにより、さまざまな程度のプロパティ カバレッジを持つさまざまなタイプの従業員クラスを作成し、このクラスでサポートされるすべてのロジックをジェネレーターに自動的に追加させることができます。

私のコードは、タイプ IEmployeeWithAddressAndPhoneNumbers の従業員が必要であると言うことができます。

これもダサく見える。

4

3 に答える 3

3

最終的には、データベースのリファクタリング (正規化) がおそらく適切であることをお勧めします。リファクタリングに取り組み、ビューを使用して、レガシ アプリケーションに期待どおりのデータベースへのインターフェイスを提供できます。つまり、たとえば、employee テーブルを employee_info、employee_contact_info、employee_assignments に分割し、これら 3 つのテーブルを結合する employee という名前のビューをレガシー アプリケーションに提供します (ロジックがより複雑)。これにより、完全に ORM ベースのソリューションに移行できる可能性があります。これは私が好むものであり、レガシー アプリケーションを快適に保つことができます。ORM と直接 SQL の混合ソリューションには進みません。

于 2008-11-16T12:51:24.617 に答える
2

「現時点では、テーブルを分割することはできません。ポートのサイズのために、レガシーアプリケーションはまだ何年も存在する必要があり、.NET コードは 3 年以内のものではありません。プロジェクトのリリース タイプですが、途中のリリースで段階的に導入されます。そのため、レガシー システムと .NET コードの両方が同じテーブルで動作する必要があります。」

2 つの言葉: マテリアライズド ビュー。

「その場で正規化」する方法はいくつかあります。

  1. マテリアライズド ビュー、別名インデックス付きビュー。これは、ソース テーブルの正規化されたクローンです。

  2. 古いテーブルから新しいテーブルへの明示的なコピー。「イク」とあなたは言います。ただし、古いアプリから機能を段階的に削除することを考慮してください。つまり、正規化された新しいテーブルにいくつかの機能が追加され、古いテーブルは適切に無視できるようになります。

  3. 明示的な双方向同期。これは難しいことですが、不可能ではありません。従来のテーブルから正しく設計されたテーブルへのコピーによって正規化します。一時的な解決策として、ストアド プロシージャとトリガーを使用してトランザクションをレガシー テーブルに複製できます。その後、変換が進むにつれて、これらのクラッジを廃止できます。

2 つの完全に異なるスキーマでこれを行うのが最も楽しいでしょう。古いデータベースには適切に設計されたスキーマがない可能性があるため、新しいデータベースには 1 つ以上の名前付きスキーマがあり、定義のバージョン管理を維持できます。

于 2008-11-16T13:13:42.420 に答える
0

私はこの特定の ORM を使用したことはありませんが、これらのタイプのデータベースで表示およびレポート用の軽量オブジェクトを提供する場合、ビューが役立つ場合があります。彼らのドキュメントによると、彼らはそのような概念をサポートしています: XPView Concepts

于 2008-11-16T13:47:40.340 に答える