Как создать связь между двумя модулями, используя EntityFramework Core? - PullRequest
2 голосов
/ 25 марта 2019

Мне нужно построить связь между двумя таблицами без использования свойства первичного ключа.

Вот мои модели сущностей

public class RealEstateProperty
{
    public int Id { get; set; }
    public string PostalCode { get; set; }
    //... List of all properties

    [ForeignKey(nameof(PostalCode))]
    public virtual RealEstatePropertyPostalCodePriority PostalCodePriority { get; set; }
}

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

    // This is a unique property on the database
    public string PostalCode { get; set; }
    public int? Sort { get; set; }

    [ForeignKey(nameof(PostalCode)), InverseProperty(nameof(RealEstateProperty.PostalCodePriority))]
    public ICollection<RealEstateProperty> Properties { get; set; }
}

Приведенные выше отношения выдают следующее исключение

InvalidOperationException: The relationship from 'RealEstateProperty.PostalCodePriority' to 'RealEstatePropertyPostalCodePriority.Properties' with foreign key properties {'PostalCode' : string} cannot target the primary key {'Id' : int} because it is not compatible. Configure a principal key or a set of compatible foreign key properties for this relationship.

Конечный результат должен выглядеть примерно так

SELECT p.Id, p.PostalCode, z.Sort
FROM RealEstateProperties AS p
LEFT JOIN RealEstatePropertyPostalCodePriorities AS z ON z.PostalCode = p.PostalCode

1 Ответ

2 голосов
/ 25 марта 2019

Чтобы быть использованным в качестве основного конца отношения, свойство non-PK PostalCode RealEstatePropertyPostalCodePriority должно быть настроено как альтернативный ключ . Затем отношение должно быть настроено на использование альтернативного ключа, а не первичного ключа.

Для обоих требуется свободный API (HasAlternateKey, HasPrincipalKey), поэтому удалите аннотации ForeignKey и InverveProperty (они в любом случае сбивают с толку):

public class RealEstateProperty
{
    public int Id { get; set; }
    public string PostalCode { get; set; }
    //... List of all properties

    //[ForeignKey(nameof(PostalCode))] <-- remove this...
    public virtual RealEstatePropertyPostalCodePriority PostalCodePriority { get; set; }
}

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

    // This is a unique property on the database
    public string PostalCode { get; set; }
    public int? Sort { get; set; }

    //[ForeignKey(nameof(PostalCode)), InverseProperty(nameof(RealEstateProperty.PostalCodePriority))] // <-- ... and this
    public ICollection<RealEstateProperty> Properties { get; set; }
}

и используйте вместо этого следующую свободную конфигурацию:

modelBuilder.Entity<RealEstatePropertyPostalCodePriority>()
    .HasMany(pcp => pcp.Properties)
    .WithOne(p => p.PostalCodePriority)
    .HasForeignKey(p => p.PostalCode)
    .HasPrincipalKey(pcp => pcp.PostalCode);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...