Entity Framework 6 Пользовательская конвенция о взаимоотношениях

c# entity-framework 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)?

Принятый ответ

Это всего лишь одно свойство или вам нужно это по всем направлениям (т. Е. Вся модель использует соглашение, где имена внешних ключей всегда «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;
    }
}


Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему