У меня была почти та же проблема, что и у вас, и я нашел следующие решения жизнеспособными.
Создание представления 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");
}
}
Теперь вы можете с легкостью повторять отображение подклассов для каждого столбца, в котором вы создаете новые типы. Проблема в том, что вы не можете обновить или вставить новые поиски в представление, поэтому вы находитесь в режиме только для чтения.
Этот метод использует имя столбца в качестве дискриминатора, поэтому не использует имя таблицы, но если в вашей таблице поиска есть повторяющиеся имена столбцов, вы можете создать базовый класс поиска для каждой таблицы и указать условие фильтра в отображении.
Другим потенциальным решением может быть использование Enums, сгенерированных шаблонами 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, если у вас есть повторяющиеся имена столбцов в информационной таблице столбцов, но разные идентификаторы таблиц.
Вы также можете различать ColumnType (числовой или текстовый) и создавать подкласс класса LookupDescription, чтобы использовать разные столбцы для свойства «Description».
Если бы вы могли предоставить структуру вашей таблицы и некоторые примеры значений, я мог бы конкретизировать эти идеи для вас.