FKに「 FK_SourceTable_TargetTable」形式で名前を付ける独自の外部キー規則を作成しようとしています。
ただし、実行すると、1つではなく2つの外部キーになります。
私のカスタム外部キー規則は次のようになります。
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);
}
}
最終結果は2つの外部キーです。1つは必要なもの(FK_WidgetFeature_Widget )と呼ばれ、もう1つはFK_WidgetIdと呼ばれます。
「property」パラメーターがnullであるかどうかに関係なく、常に同じ名前を返すようにOurForeignKeyConventionを変更すると、単一のFKを正しく取得できますが、FK名の「SourceTable」部分を取得できません。
誰かが私がここで間違っていることを説明できますか?GetKeyNameが2回呼び出されるのはなぜですか?また、呼び出しの1つが「property」パラメーターの値を提供しないのはなぜですか?