2011-07-01 24 views
3

我正在構建一個應用程序,用於存儲查找值在通用表中的實際數據庫(實際上它保存在四個不同的表中)。這意味着實體表存儲「id」查找值和元數據表保存着這個值的「描述」。NHibernate映射實體到通用查找表

元數據表被分解如下:

  • TableInfo
  • ColumnInfo
  • 的BusinessInfo
  • LookupDescriptionInfo

以獲取查找描述,你參加所有四個表和指定表名,列名和查找ID。查找說明信息表包含兩列 - 一列用於文本值,一列用於數字值。

我想每個查找類型都有一個單獨的類(例如,基於Widget.WidgetTypeId值,我的Widget類將與「WidgetType」具有多對一關係)。完成這個?數據模型被超過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模板生成的枚舉。儘管這也是一種只讀方法。


你也可以映射出每個查找表爲一類,並使用鑑別模式從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... 

同樣您也可以選擇決定要辨別出一些XTable類,如果你有在列信息表,但不同TABLEID的重複的列名。

您還可以區分ColumnType(數字或文本)和子類LookupDescription類,以使用「Description」屬性的不同列。

如果你可以提供你的表格結構和一些樣本值,我可以爲你更多地提供這些想法。

+0

好東西!我結束了你的第一個選擇的輕微變化。我創建了一個視圖,使用

- - 作爲唯一ID,
- 作爲鑑別器。我有一個包含Id,LookupId和LookupDescription屬性的Lookup抽象類,然後爲每個單獨的查找實體創建了子類。每個查找都有相同的列,所以我的具體查找類不會添加任何新的屬性。 –