我需要在不使用主键属性的情况下在两个表之间建立关系。
这是我的实体模型
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
答案 0 :(得分:2)
为了用作关系的主要终点,PostalCode
的非PK属性RealEstatePropertyPostalCodePriority
必须配置为alternate key。然后必须将关系配置为使用备用键而不是主键。
两者都需要流畅的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);