Entity Framework - 由 3 个外键组成的复合主键

Entity Framework - Composite Primary Key formed by 3 Foreign Keys

我正在创建 4 table 之间的关系:Provider、CostumerSite、DrmType 和 Drm。

关系:

在 Drm table 中有一个组合键由其他 3 个 table 的主键组成。这是代码:

public partial class Provider
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProviderId { get; set; }

    [StringLength(128)]
    [Required]
    public string Title { get; set; }

    // one-to-many
    public virtual ICollection<Content> Contents { get; set; }

    public virtual Drm Drm { get; set; }

}

 public partial class CustomerSite
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CustomerSiteId { get; set; }

    [Required]
    [StringLength(128)]
    public string Name { get; set; }

    [Required]
    [StringLength(128)]
    public string Username { get; set; }

    [Required]
    [StringLength(128)]
    public string Password { get; set; }

    // many-to-many
    public virtual ICollection<Content> Contents { get; set; }

    // one-to-one
    public virtual Drm Drm { get; set; }
}

 public partial class DrmType
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int DrmTypeId { get; set; }

    [Required]
    [StringLength(128)]
    public string Name { get; set; }

    // one-to-one
    public virtual Drm Drm { get; set; }
}

public partial class Drm
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int DrmId { get; set; }

    // one-to-one relation
    [Key, Column(Order = 1), ForeignKey("CustomerSite")]
    public int CustomerSiteId { get; set; }

    // one-to-one relation
    [Key,  Column(Order = 2), ForeignKey("Provider")]
    public int ProviderId { get; set; }

    // one-to-one relation
    [Key,  Column(Order = 3), ForeignKey("DrmType")]
    public int DrmTypeId { get; set; }

    public virtual Provider Provider { get; set; }
    public virtual CustomerSite CustomerSite { get; set; }
    public virtual DrmType DrmType { get; set; }
}

这是正确的吗?在此之后,我正在使用 onModel 函数:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Entity<Drm>()
        .HasKey(d => new { d.ProviderId, d.CustomerSiteId, d.DrmType });

    }

但是这样,当我启动 "Enable-Migrations -EnableAutomaticMigrations -Force" 命令时,它显示错误:

One or more validation errors were detected during model generation:

Drm_CustomerSite_Source: : Multiplicity is not valid in Role 'Drm_CustomerSite_Source' in relationship 'Drm_CustomerSite'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be ''. Drm_Provider_Source: : Multiplicity is not valid in Role 'Drm_Provider_Source' in relationship 'Drm_Provider'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be ''.

你能解释一下如何解决这个问题吗?谢谢

解决此问题的最简单方法是为 DRM table 提供自己的 ID 并制作 3 个字段外键。 我不知道您要规范化到什么程度,但通常会这样做以防止不必要的复杂代码。 保持干净,保持简单

根据您的模型,Drm 不应有自己的 "id"。所以,它应该是这样的:

public partial class Drm
{
    //remove this property
    //[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    //public int DrmId { get; set; }

    // one-to-one relation
    [Key, Column(Order = 1), ForeignKey("CustomerSite")]
    public int CustomerSiteId { get; set; }

    // one-to-one relation
    [Key,  Column(Order = 2), ForeignKey("Provider")]
    public int ProviderId { get; set; }

    // one-to-one relation
    [Key,  Column(Order = 3), ForeignKey("DrmType")]
    public int DrmTypeId { get; set; }

    public virtual Provider Provider { get; set; }
    public virtual CustomerSite CustomerSite { get; set; }
    public virtual DrmType DrmType { get; set; }
}

由于您在 class 声明中提供了 [Key] 属性,因此无需在模型绑定中声明 HasKey。所以,删除这一行:

modelBuilder.Entity<Drm>()
    .HasKey(d => new { d.ProviderId, d.CustomerSiteId, d.DrmType });

编辑

ProviderCustomerSiteDrmType 必须有 Drm.

的集合
public partial class Provider
{
    //...
    //public virtual Drm Drm { get; set; }
    public virtual ICollection<Drm> Drms { get; set; }
}

public partial class CustomerSite
{
    //...
    //public virtual Drm Drm { get; set; }
    public virtual ICollection<Drm> Drms { get; set; }
}

public partial class DrmType
{
    //public virtual Drm Drm { get; set; }        
    public virtual ICollection<Drm> Drms { get; set; }
}

希望对您有所帮助!