首页 > 解决方案 > 复合共享键和实体

问题描述

我正在开发一个数据库,其中表具有复合键,并且该键的一部分在表之间共享。我不知道如何在实体中正确设置关系。

想象一下:

public class Sale
{
        public long ID { get; set; } //Key
        public long RetailerID { get; set; } //Key
        public virtual Location Location { get; set; } //Foreign, Many-to-One
}
public class Location
{
        public long ID { get; set; } //Key
        public long RetailerID { get; set; } //Key
        public virtual IEnumerable<Sale> Sales { get; set; } //Relationship, One-to-Many
}

两者都使用 fluent API 来定义复合键OnModelCreating

modelBuilder.Entity<Sale>().HasKey(x => new { x.RetailerID, x.ID });
modelBuilder.Entity<Location>().HasKey(x => new { x.RetailerID, x.ID });

但是,我不确定如何完成此操作以建立正确的关系,因为它将自己设置为具有重复的 RetailerID 列,这是不必要的。这应该如何正确完成(如果有的话?)

标签: c#sql-serverentity-framework-core

解决方案


可以通过多种方式实现,所有方式都包括额外的LocationIDFK 属性(显式或阴影)。

  • 使用 shadow FK 属性(不修改实体模型):

数据注释:

[Required]
[ForeignKey("RetailerID, LocationID")]
public virtual Location Location { get; set; } //Foreign, Many-to-One

流畅的 API:

modelBuilder.Entity<Sale>()
    .HasOne(e => e.Location)
    .WithMany(e => e.Sales)
    .HasForeignKey("RetailerID", "LocationID")
    .IsRequired();
  • 具有显式 FK 属性

模型:

public long LocationID { get; set; } // added
public virtual Location Location { get; set; } //Foreign, Many-to-One

数据注释:

[ForeignKey("RetailerID, LocationID")]
public virtual Location Location { get; set; } //Foreign, Many-to-One

流畅的 API:

modelBuilder.Entity<Sale>()
    .HasOne(e => e.Location)
    .WithMany(e => e.Sales)
    .HasForeignKey(e => new { e.RetailerID, e.LocationID });

(注意:使用数据注释或 fluent API - 两者都不需要)


推荐阅读