2011-07-01 12 views
3

私は、ルックアップ値を汎用テーブルに格納するレガシーデータベースに対してアプリケーションを構築しています(実際には4つの異なるテーブルに保持されています)。ルックアップ値およびメタデータテーブルは、この値の「記述」を保持する。NHibernateマップエンティティから汎用ルックアップテーブル

メタデータテーブルは、次のように分類されます。

  • TableInfo
  • ColumnInfo
  • BusinessInfo
  • LookupDescriptionInfo

ルックアップの説明を取得するには、あなたはすべての4つのテーブルを結合し、テーブル名、カラム名、ルックアップIDを指定します。ルックアップ記述情報テーブルには、テキスト値用と数値用の2つの列が含まれています。

それぞれのルックアップタイプに対して別のクラスを用意したいと思います(たとえば、私のWidgetクラスは、Widget.WidgetTypeIdの値に基づいて「WidgetType」と多対1の関係にあります)。これを達成する?データモデルは1000を超えるRPGプログラムで使用されているため、変更することはできません。

答えて

5

私はあなたとほぼ同じ問題を抱えており、以下の解決策が実行可能であることがわかりました。

SQLビューの作成

-- I'm guessing at the table join structure here 
create view LookupView 
as 
select t.TableName, 
    ci.ColumnName, 
    bi.Id, --This ID column needs to be the one used as the FK from other tables 
    bi.*, --Or whatever columns you need 
    coalesce(di.TextDescription, di.NumericDescription) as Description 
from TableInfo t 
join ColumnInfo ci on t.Id=ci.TableId 
join BusinessInfo bi on bi.Id=ci.BusinessId 
join LookupDescriptionInfo di on di.id=ci.id 

ベースのルックアップクラスを作成します

public class Lookup { 
    public virtual string Tablename {get; set;} 
    public virtual string ColumnName {get; set;} 
    public virtual string Description {get; set;} 
    public virtual int Id {get; set;} 
    //Other BusinessInfo properties 
} 

継承LookupClass

を作成
public class ArmourLookup : Lookup{} 

あなたのビジネスオブジェクトにArmourLookupクラスを使用します。

public class HeroArmour{ 
    //Usual properties etc.... 
    public virtual ArmourLookup Lookup {get; set;} 
} 

サブクラスを作成

は、マッピングが今、あなたはあなたが簡単に新しい種類を作成しているすべての列のためのサブクラスのマッピングを繰り返すことができ
public class LookupMap : ClassMap<Lookup> { 
    public LookupMap(){ 
     Id(x=>x.Id).GeneratedBy.Assigned(); //Needs to be a unique ID 
     Map(x=>x.Tablename); 
     Map(x=>x.ColumnName); 
     Map(x=>x.Description); 
     //Business Info property mappings here 
     Table("LookupView") 
     DiscriminateSubClassesOnColumn<string>("ColumnName"); 
     ReadOnly(); 
    } 
} 

public class ArmourLookupMap : SubClassMap<ArmourLookup> { 
    public ArmourLookupMap(){ 
     DiscriminatorValue("ArmourColumn"); 
    } 
} 

を設定判別します。ここでの問題は、読み取り専用モードにあるように、ビューに新しいルックアップを更新または挿入できないことです。

この方法では、列名をディスクリミネータとして使用するため、テーブル名は使用しませんが、ルックアップテーブルに列名が重複する場合は、すべてのテーブルに対して基本ルックアップクラスを作成し、


また、ルックアップテーブルのT4テンプレートで生成された列挙型を使用することもできます。これは読み取り専用のアプローチですが。


また、各ルックアップテーブルをクラスとしてマップし、discoliminatorパターンを使用してColumnInfoテーブルからさまざまなタイプを取得することもできます。

public class TableInfo { 
    public virtual int Id {get; set;} 
    public virtual string Tablename {get; set;} 
    public IList<ColumnInfo> Columns {get; set;} 
} 

public class ColumnInfo { 
    public virtual int Id {get; set;} 
    public virtual TableInfo TableInfo {get; set;} 
    public virtual BusinessInfo BusinessInfo {get; set;} 
    public virtual LookupDescriptionInfo LookupDescriptionInfo {get; set;} 
    //Other properties 
} 

public class ArmourInfoColumn : ColumnInfo { 
    //In the mapping you would discriminate on the columnname column. 
} 

etc... 

は再び、必要に応じて、あなたは、列情報テーブルが異なるTABLEIDの中に重複する列名を持っている場合、一部のXTableクラスを区別することを決定することができます。

また、ColumnType(数値またはテキスト)を区別し、LookupDescriptionクラスをサブクラス化して、 "Description"プロパティに異なる列を使用することもできます。

テーブル構造といくつかのサンプル値を提供できれば、私はこれらのアイデアをより魅力的にすることができます。

+0

素晴らしいもの!私はあなたの最初のオプションのわずかなバリエーションで終わった。私は

- - を一意のIDとして使用し、
- を弁別子として使用するビューを作成しました。 Id、LookupId、およびLookupDescriptionの各プロパティを含むLookup抽象クラスがあり、次に個々のルックアップエンティティごとにサブクラスを作成しました。各ルックアップには同じ列があるので、具体的なルックアップクラスは新しいプロパティを追加しません。 –

関連する問題