实体框架 - 由3个外键组成的复合主键

时间:2016-02-25 13:56:13

标签: c# sql-server entity-framework code-first ef-migrations

我在4个表之间建立关系:Provider,CostumerSite,DrmType和Drm。

关联: enter image description here

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

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

    }

但是这样,当我启动&#34;启用 - 迁移-EnableAutomaticMigrations -Force&#34;命令它显示错误:

  

在模型生成期间检测到一个或多个验证错误:

     

Drm_CustomerSite_Source ::多重性在角色中无效   &#39; Drm_CustomerSite_Source&#39;在关系&Drm_CustomerSite&#39;。因为   Dependent Role属性不是关键属性,鞋面   依赖角色的多样性的界限必须是&#39; &#39;。   Drm_Provider_Source ::多重性在Role中无效   &#39; Drm_Provider_Source&#39;在关系&#39; Drm_Provider&#39;。因为   依赖角色属性不是关键属性,即上限   依赖角色的多样性必须是&#39; &#39;。

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

2 个答案:

答案 0 :(得分:1)

根据您的模型,EFG EFG 不应该有自己的&#34; id&#34;。所以,它应该是这样的:

Drm

由于您在类声明中提供了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; } } 属性,因此您无需在模型绑定中声明[Key]。所以,删除这一行:

HasKey

修改

modelBuilder.Entity<Drm>() .HasKey(d => new { d.ProviderId, d.CustomerSiteId, d.DrmType }); ProviderCustomerSite必须包含DrmType的集合。

Drm

希望这有帮助!

答案 1 :(得分:0)

解决此问题的最简单方法是为DRM表提供自己的ID并使3个字段为外键。 我不知道你正在规范化的范围,但它通常是为了防止不必要的复杂代码。 保持清洁,保持简单