0

我正在尝试创建自己的外键约定,以“ 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”参数是否为空,那么我正确地获得了一个 FK - 但我无法获得我的 FK 名称的“ SourceTable ”部分。

谁能解释我在这里做错了什么?为什么 GetKeyName 被调用两次?为什么其中一个调用没有为“property”参数提供值?

4

1 回答 1

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));
    }
}
于 2011-09-27T23:26:45.913 回答