长版:
我正在使用Fluent NHibernate来配置NHibernate,并且我有一个自定义外键约定,当我使用别名表和列时失败。
我的表使用一种约定,其中主键始终称为“PK”,外键是“FK”,后跟外键表的名称,例如“FKParent”。例如:
CREATE TABLE OrderHeader (
PK INT IDENTITY(1,1) NOT NULL,
...
)
CREATE TABLE OrderDetail (
PK INT IDENTITY(1,1) NOT NULL,
FKOrderHeader INT NOT NULL,
...
)
为了完成这项工作,我构建了一个自定义的ForeignKeyConvention,如下所示:
public class AmberForeignKeyConvention : ForeignKeyConvention
{
protected override string GetKeyName( Member member, Type type )
{
if ( member == null )
return "FK" + type.Name; // many-to-many, one-to-many, join
return "FK" + member.Name; // many-to-one
}
}
只要我的实体名称与表格相同,这就有效。但是当它们没有时就会中断。例如,如果我想将OrderDetail表映射到名为Detail的类,我可以这样做:
public class DetailMap : ClassMap<Detail>
{
public DetailMap()
{
Table( "OrderDetail" );
Id( o => o.PK );
References( o => o.Order, "FKOrderHeader" );
...
}
}
映射适用于加载单个实体,但是当我尝试使用连接运行任何类型的复杂查询时,它都会失败,因为AmberForeignKeyConvention类对列的映射方式做出了错误的假设。即,它假定外键应为“FK”+ type.Name,在本例中为Order,因此它调用外键“FKOrder”而不是“FKOrderHeader”。
正如我上面所说:我的问题是,我如何从ForeignKeyConvention内部访问映射,以确定给定类型的映射表名称(就此而言,它们的映射列名称也是如此)? this question的答案似乎暗示了正确的方向,但我不明白所涉及的课程是如何协同工作的。当我查看文档时,对于我查找的类(例如IdMapping class)来说,它是非常稀疏的。(
答案 0 :(得分:1)
想法是加载映射
public class AmberForeignKeyConvention : ForeignKeyConvention
{
private static IDictionary<Type, string> tablenames;
static AmberForeignKeyConvention()
{
tablenames = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => typeof(IMappingProvider).IsAssignableFrom(t))
.ToDictionary(
t => t.BaseType.GetGenericArguments()[0],
t => ((IMappingProvider)Activator.CreateInstance(t)).GetClassMapping().TableName);
}
protected override string GetKeyName( Member member, Type type )
{
return "FK" + tablenames[type]; // many-to-one
}
}