2

我已阅读有关实体框架 6 中约定文档。但它不包含关系约定。

假设我有以下模型:

[TablePrefix("mst")]
public class Guru
{
    public int Id { get; set; }

    public int? IdKotaLahir { get; set; }

    public virtual Kota KotaLahir { get; set; }
}

我希望属性IdKotaLahir是导航属性的外键KotaLahir。外键名称是"Id"+<NavigationPropertyName>. 是否可以使用当前版本的实体框架(EF 6 alpha 3)?

4

2 回答 2

2

它只是一个属性,还是您需要全面使用(即整个模型使用外键名称始终为“Id”+ NavigationPropertyName 的约定)?如果您只想要单个实体的外键,则最好仅使用该ForeignKey属性:

public class Guru
{
    public int Id { get; set; }

    public int? IdKotaLahir { get; set; }

    [ForeignKey("IdKotaLahir")]
    public virtual Kota KotaLahir { get; set; }
}

这适用于 EF5 和 EF6。在 EF6 中,您可以使用自定义约定来配置外键属性。这是我想出的自定义约定:

public class NavigationPropertyConfigurationConvention
    : IConfigurationConvention<PropertyInfo, NavigationPropertyConfiguration>
{
    public void Apply(
        PropertyInfo propertyInfo, Func<NavigationPropertyConfiguration> configuration)
    {
        var foreignKeyProperty = 
            propertyInfo.DeclaringType.GetProperty("Id" + propertyInfo.Name);

        if (foreignKeyProperty != null && configuration().Constraint == null)
        {
            var fkConstraint = new ForeignKeyConstraintConfiguration();
            fkConstraint.AddColumn(foreignKeyProperty);

            configuration().Constraint = fkConstraint;
        }           
    }
}

我还为此写了一篇更详细的博客文章

于 2013-03-23T22:13:57.203 回答
2

在 EF6 中,接受答案的约定不再有效,因为 IConfigurationConvention 是内部的。处理这种情况的方法是从 ForeignKeyDiscoveryConvention 继承。

public class MyForeignKeyDiscoveryConvention : ForeignKeyDiscoveryConvention
{
    protected override bool MatchDependentKeyProperty(AssociationType associationType, AssociationEndMember dependentAssociationEnd,
        EdmProperty dependentProperty, EntityType principalEntityType, EdmProperty principalKeyProperty)
    {
        string navigationPropertyName = ((System.Reflection.PropertyInfo)dependentAssociationEnd.MetadataProperties.GetValue("ClrPropertyInfo", false).Value).Name;

        // The standard foreign key property to look for is NavigationProperty_PrimaryKeyName (e.g. "TableName_Id"). 
        // Use the below line to remove that underscore.
        //return dependentProperty.Name == navigationPropertyName + principalKeyProperty.Name;

        // Use the following for the IdKotaLahir scenario
        return dependentProperty.Name == "Id" + navigationPropertyName;
    }
}
于 2017-05-05T15:46:02.697 回答