如何使用EntityFramework Core在两个模块之间创建关系?

时间:2019-03-24 23:28:24

标签: c# entity-framework-core

我需要在不使用主键属性的情况下在两个表之间建立关系。

这是我的实体模型

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 个答案:

答案 0 :(得分:2)

为了用作关系的主要终点,PostalCode的非PK属性RealEstatePropertyPostalCodePriority必须配置为alternate key。然后必须将关系配置为使用备用键而不是主键。

两者都需要流畅的API(HasAlternateKeyHasPrincipalKey),因此请删除ForeignKeyInverveProperty批注(无论如何它们都会造成混淆):

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