Pau*_*ner 9 naming-conventions fluent-nhibernate
我有一个数据库模式,其中外键名称的约定是:
ForeignTable.Name + ForeignTable.PrimaryKeyName
Run Code Online (Sandbox Code Playgroud)
因此,对于Child
引用Parent
具有名为主键列的表的表Key
,外键将如下所示ParentKey
.
有没有办法在我的Fluent NHibernate映射中创建这个约定?
目前我正在使用这样的ForeignKeyConvention
实现:
public class ForeignKeyNamingConvention : ForeignKeyConvention
{
protected override string GetKeyName(PropertyInfo property, Type type)
{
if (property == null)
{
// Relationship is many-to-many, one-to-many or join.
if (type == null)
throw new ArgumentNullException("type");
return type.Name + "ID";
}
// Relationship is many-to-one.
return property.Name + "ID";
}
}
Run Code Online (Sandbox Code Playgroud)
对于所有以"ID"为主键的类型,这完全符合我的要求.我想要做的是将常量"ID"替换为所引用类型的主键的名称.
如果使用Fluent NHibernate目前无法做到这一点,我很乐意接受这个答案.
查看约定,特别是实现自定义外键约定.
更新:
这是一个例子.假设以下域:
public class Parent
{
public virtual int Id { get; set; }
}
public class Child
{
public virtual string Id { get; set; }
public virtual Parent Parent { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
需要映射到此架构:
create table Child(
Id integer primary key,
ParentId integer
)
create table Parent(
Id integer primary key
)
Run Code Online (Sandbox Code Playgroud)
你可以使用这个约定:
public class CustomForeignKeyConvention : IReferenceConvention
{
public void Apply(IManyToOneInstance instance)
{
instance.Column(instance.Class.Name + "Id");
}
}
Run Code Online (Sandbox Code Playgroud)
并创建会话工厂:
var sf = Fluently
.Configure()
.Database(
SQLiteConfiguration.Standard.UsingFile("data.db3").ShowSql()
)
.Mappings(
m => m.AutoMappings.Add(AutoMap
.AssemblyOf<Parent>()
.Where(t => t.Namespace == "Entities")
.Conventions.Add<CustomForeignKeyConvention>()
)
)
.BuildSessionFactory();
Run Code Online (Sandbox Code Playgroud)
如果您可以获得Mapping<T>
某个类的 ,则可以获得其 Id 列的名称。
public class MyForeignKeyConvention: ForeignKeyConvention
{
public static IList<IMappingProvider> Mappings = new List<IMappingProvider>();
protected override string GetKeyName( System.Reflection.PropertyInfo property, Type type )
{
var pk = "Id";
var model = new PersistenceModel();
foreach( var map in Mappings ) {
model.Add( map );
}
try {
var mymodel = (IdMapping) model.BuildMappings()
.First( x => x.Classes.FirstOrDefault( c => c.Type == type ) != null )
.Classes.First().Id;
Func<IdMapping, string> getname = x => x.Columns.First().Name;
pk = getname( mymodel );
} catch {
}
if (property == null) {
return type.Name + pk;
}
return type.Name + property.Name;
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以通过一些管道来获取 Mapping 对象。
的构造函数ClassMap<T>
可以传递this
到我们的映射器集合中。
对于AutoMapping<T>
,我们可以按如下方式使用 Override 。
.Mappings( m => m.AutoMappings.Add( AutoMap.AssemblyOf<FOO>()
.Override<User>( u => {
u.Id( x => x.Id ).Column( "UID" );
MyForeignKeyConvention.Mappings.Add( u );
}
)
Run Code Online (Sandbox Code Playgroud)