Dan*_*rth 5 .net c# nhibernate fluent-nhibernate
假设我有以下两个类:
public class User : Entity
{
public virtual IList<Item> Items { get; set; }
}
public class Item : Entity
{
public virtual User Owner { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我创建了两个映射类:
public class UserMap : ClassMap<User>
{
public UserMap()
{
Id(x => x.Id);
HasMany(x => x.Items);
}
}
public class ItemMap : ClassMap<Item>
{
public ItemMap()
{
Id(x => x.Id);
References(x => x.Owner);
}
}
Run Code Online (Sandbox Code Playgroud)
这将导致Item具有列UserId和列的表OwnerId.当我KeyColumn("OwnerId")在HasMany映射上使用时,它只适用于OwnerId列,但我想避免这种情况.有没有办法告诉NHibernate,使用映射创建的列ItemMap?
为什么我要避免显式指定列:
根据OwnerId属性的名称和一些规则自动生成列名.如果我改变规则或属性名称,我也需要记住改变它KeyColumn.所以,基本上,它不是重构保存.
更新:修复了错误
如果你应用地图中的规则
public static void KeyColumnFromReference<TChild>(
this OneToManyPart<TChild> collectionmap, ClassMap<TChild> map, Expression<Func<TChild, object>> referenceprop)
{
string propertyname = GetPropertyName(referenceprop);
var column = ((IMappingProvider)map).GetClassMapping()
.References.First(m => m.Name == propertyname)
.Columns.First().Name;
collectionmap.KeyColumn(column);
}
public static void KeyColumnFromReference<T, TChild>(
this OneToManyPart<TChild> collectionmap, ClassMap<TChild> map)
{
var column = ((IMappingProvider)map).GetClassMapping()
.References.First(m => m.Type == typeof(TChild))
.Columns.First().Name;
collectionmap.KeyColumn(column);
}
public UserMap()
{
HasMany(x => x.Items)
.KeyColumnFromReference<User, Item>(new ItemMap());
// or
HasMany(x => x.Items)
.KeyColumnFromReference(new ItemMap(), u => u.Owner);
}
Run Code Online (Sandbox Code Playgroud)
如果您将规则作为约定应用,那么您需要IHasManyConvention在 和 propertyname 上实现并应用相同的规则EntityType(您必须通过 ChildType 的反射来获取)
更新:
class ForeignKeyConvention : IHasManyConvention
{
public void Apply(IOneToManyCollectionInstance instance)
{
// to force the compiler to take the Name property and not the Name method
string propertyName = ((ICollectionInspector)instance).Name;
// should be equal to the convention for the reference key column
instance.Key.Column(propertyName + instance.EntityType.Name + "id");
}
}
Run Code Online (Sandbox Code Playgroud)