我正在尝试创建自己的外键约定,它将以“ FK_SourceTable_TargetTable ”格式命名FK。
然而,当我运行它时,我最终使用两个外键而不是一个。
我的自定义外键约定如下所示:
public class OurForeignKeyConvention : ForeignKeyConvention
{
protected override string GetKeyName(Member property, Type type)
{
if (property == null)
return string.Format("FK_{0}Id", type.Name); // many-to-many, one-to-many, join
if (property.Name == type.Name)
return string.Format("FK_{0}_{1}", property.DeclaringType.Name, type.Name);
return string.Format("FK_{0}_{1}_{2}", property.DeclaringType.Name, property.Name, type.Name);
}
}
我的代码来运用它:
[TestMethod]
public void ShouldBeAbleToBuildSchemaWithOurConventions()
{
var configuration = new Configuration();
configuration.Configure();
Fluently
.Configure(configuration)
.Mappings(m => m.FluentMappings
.AddFromAssemblyOf<Widget>()
.Conventions.Add<OurForeignKeyConvention>()
)
.BuildSessionFactory();
new SchemaExport(configuration).Create(false, true);
}
我的课程和映射:
public class Widget
{
public virtual int Id { get; set; }
public virtual string Description { get; set; }
public virtual WidgetType Type { get; set; }
public virtual ISet<WidgetFeature> Features { get; set; }
}
public class WidgetFeature
{
public virtual int Id { get; set; }
public virtual Widget Widget { get; set; }
public virtual string FeatureDescription { get; set; }
}
public class WidgetMap : ClassMap<Widget>
{
public WidgetMap()
{
Id(w => w.Id);
Map(w => w.Description);
HasMany(w => w.Features).Cascade.AllDeleteOrphan().Inverse();
}
}
public class WidgetFeatureMap : ClassMap<WidgetFeature>
{
public WidgetFeatureMap()
{
Id(w => w.Id);
Map(w => w.FeatureDescription);
References(w => w.Widget);
}
}
最终结果是两个外键,一个叫做我想要的 - FK_WidgetFeature_Widget - 另一个叫做 FK_WidgetId 。
如果我将OurForeignKeyConvention更改为始终返回相同的名称,无论“property”参数是否为null,那么我正确地获得单个FK - 但我无法获得“ SourceTable ”部分FK名称。
有谁能解释我在这里做错了什么?为什么GetKeyName被调用两次?为什么其中一个调用没有为“property”参数提供值?
答案 0 :(得分:1)
卫生署。 ForeignKeyConvention提供FK列的名称。我应该使用的是IHasManyConvention,它可以用来命名FK约束本身。
public class OurForeignKeyConstraintNamingConvention : IHasManyConvention
{
public void Apply(IOneToManyCollectionInstance instance)
{
instance.Key.ForeignKey(string.Format("FK_{0}_{1}", instance.Relationship.Class.Name, instance.EntityType.Name));
}
}