簡體   English   中英

NHibernate map 實體到通用查找表

[英]NHibernate map entity to generic lookup table

我正在針對將查找值存儲在通用表中的遺留數據庫構建應用程序(實際上它保存在四個不同的表中。)這意味着實體表存儲查找值的“id”,元數據表保存“描述”這個值。

元數據表分解如下:

  • 表信息
  • 列信息
  • 商業資訊
  • 查找描述信息

要獲取查找描述,您需要連接所有四個表並指定表名、列名和查找 ID。 查找描述信息表包含兩列——一列用於文本值,一列用於數值。

我想為每種查找類型有一個單獨的 class(例如,我的 Widget class 將與基於 Widget.WidgetTypeId 值的“WidgetType”建立多對一關系。)有哪些策略可以實現這一點? 數據 model 被 1000 多個 RPG 程序使用,因此無法更改。

我遇到了與您幾乎完全相同的問題,並發現以下解決方案是可行的。

創建 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

創建基本查找 Class

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 class。

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");
    }
}

現在,您可以輕松地為您創建新類型的每一列重復子類映射。 這里的問題是您無法在視圖中更新或插入新的查找,因此您處於只讀模式。

此方法使用列名作為鑒別器,因此無需表名,但如果您的查找表中有重復的列名,您可以為每個表創建基本查找 class 並在映射中指定過濾條件。


另一種可能的解決方案是使用由查找表中的 T4 模板生成的枚舉。 雖然這也是一種只讀方法。


您還可以將每個查找表 map 作為 class 並使用鑒別器模式從 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 class 子類化為“描述”屬性使用不同的列。

如果您可以提供您的表格結構和一些示例值,我可以為您進一步充實這些想法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM