Entity Framework 6 Соглашение о таможенных отношениях

Я прочитал эту документацию о соглашении в Entity Framework 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)?

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

Я также написал более подробный пост в блоге по этому вопросу.

В 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;
    }
}
Другие вопросы по тегам