0

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」パラメーターの値を提供しないのはなぜですか?

4

1 に答える 1

1

どー。ForeignKeyConvention は、FK 列の名前を提供します。私が使用すべきだったのは、FK 制約自体に名前を付けるために使用できる IHasManyConvention です。

public class OurForeignKeyConstraintNamingConvention : IHasManyConvention
{
    public void Apply(IOneToManyCollectionInstance instance)
    {
        instance.Key.ForeignKey(string.Format("FK_{0}_{1}", instance.Relationship.Class.Name, instance.EntityType.Name));
    }
}
于 2011-09-27T23:26:45.913 に答える