开发者

My custom ForeignKeyConvention is resulting in two foreign keys being created instead of one

开发者 https://www.devze.com 2023-04-07 15:35 出处:网络
I am trying to create my own foreign key convention that will name the FK in \"FK_SourceTable_TargetTable\" format.

I am trying to create my own foreign key convention that will name the FK in "FK_SourceTable_TargetTable" format.

However, when I run it I end up with two foreign keys instead of one.

My custom foreign key convention looks like this:

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);
    }
}

My code to exercise it:

    [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);
    }

My classes and mappings:

public class Widget
{
    public virtual int Id { get; set; }
    public virtual string Descr开发者_开发百科iption { 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);
    }
}

The end result is two foreign keys, one called what I want - FK_WidgetFeature_Widget - and another one called FK_WidgetId.

If I change OurForeignKeyConvention to always return the same name regardless of whether the "property" parameter is null then I correctly get a single FK - but I then cannot get the "SourceTable" part of my FK name.

Can anyone explain what I am doing wrong here? Why is GetKeyName called twice? And why does one of the calls not provide a value for the "property" parameter?


Doh. ForeignKeyConvention provides the name for the FK column. What I should have been using is the IHasManyConvention, which can be used to name the FK constraint itself.

public class OurForeignKeyConstraintNamingConvention : IHasManyConvention
{
    public void Apply(IOneToManyCollectionInstance instance)
    {
        instance.Key.ForeignKey(string.Format("FK_{0}_{1}", instance.Relationship.Class.Name, instance.EntityType.Name));
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号