EF中的复合键

时间:2015-08-28 08:36:28

标签: c# entity-framework

我似乎无法理解EF如何处理复合键。当我尝试'add-migration Initial'时,下面的代码返回“属性'QuestionID'不能用作实体QuestionQuestionTypesModel'的关键属性,因为属性类型不是有效的键类型。只有标量类型,字符串和字节[]是受支持的密钥类型。“

我还尝试设置注释而不是覆盖OnModelCreating。我用[Key,Column(Order = 0)]

任何人都能给我任何关于我做错的线索吗?或者解释为了更好地理解手头的问题会发生什么?

          public class QuestionModel
    {
        [Key]
        [HiddenInput(DisplayValue = false)]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public Guid ID { get; set; }

        [Required]
        [StringLength(250)]
        public string Question { get; set; }
   }


  public class QuestionTypeModel
    {
        [Key]
        [HiddenInput(DisplayValue = false)]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public Guid ID { get; set; }

        [Required]
        [StringLength(250)]
        public string TypeName { get; set; }
    }


  public class QuestionQuestionTypesModel
    {
        public virtual QuestionModel QuestionID {get;set;}
        public virtual QuestionTypeModel QuestionTypeID { get; set; }
    }

public class InnuendoContext : DbContext
    {

      public IContext() : base("DefaultConnection")
        {
        }

        public DbSet<QuestionTypeModel> QuestionTypes { get; set; }
        public DbSet<QuestionModel> Questions { get; set; }
        public DbSet<QuestionQuestionTypesModel> QuestionQuestionTypes { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            modelBuilder.Entity<QuestionQuestionTypesModel>().HasKey(a => new { a.QuestionID, a.QuestionTypeID });
        }
}

2 个答案:

答案 0 :(得分:1)

您必须创建表所需的属性,这些属性也是系统的外键。通过设置此结构:

public class QuestionQuestionTypesModel
{
    [Key, Column(Order = 1), ForeignKey("Question")]
    public Guid QuestionID { get; set; }
    [Key, Column(Order = 2), ForeignKey("QuestionType")]
    public Guid QuestionTypeID { get; set; }

    public virtual QuestionModel Question { get; set; }
    public virtual QuestionTypeModel QuestionType { get; set; }
}

您可以进行此迁移:

public override void Up()
{
    CreateTable(
        "dbo.QuestionModel",
        c => new
        {
            ID = c.Guid(nullable: false, identity: true),
            Question = c.String(nullable: false, maxLength: 250),
        })
        .PrimaryKey(t => t.ID);

    CreateTable(
        "dbo.QuestionTypeModel",
        c => new
        {
            ID = c.Guid(nullable: false, identity: true),
            TypeName = c.String(nullable: false, maxLength: 250),
        })
        .PrimaryKey(t => t.ID);

    CreateTable(
        "dbo.QuestionQuestionTypesModel",
        c => new
            {
                QuestionID = c.Guid(nullable: false),
                QuestionTypeID = c.Guid(nullable: false),
            })
        .PrimaryKey(t => new { t.QuestionID, t.QuestionTypeID })
        .ForeignKey("dbo.QuestionModel", t => t.QuestionID, cascadeDelete: true)
        .ForeignKey("dbo.QuestionTypeModel", t => t.QuestionTypeID, cascadeDelete: true)
        .Index(t => t.QuestionID)
        .Index(t => t.QuestionTypeID);
}

<强>更新 刚看到你的评论。如果您只有多对多的关系,并且您不需要任何其他属性,则可以执行以下操作:

public class QuestionModel
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public Guid ID { get; set; }

    [Required]
    [StringLength(250)]
    public string Question { get; set; }
    //One question has many QuestionTypes
    public virtual ICollection<QuestionTypeModel> QuestionTypes { get; set; }
}


public class QuestionTypeModel
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public Guid ID { get; set; }

    [Required]
    [StringLength(250)]
    public string TypeName { get; set; }
    //One QuestionType has many Questions
    public virtual ICollection<QuestionModel> Questions { get; set; }
}

这将产生相同的迁移,但会使您的数据层清晰。

答案 1 :(得分:0)

modelBuilder.Entity<QuestionQuestionTypesModel>().HasKey(a => new { a.QuestionID, a.QuestionTypeID });

QuestionID和QuestionTypeID都是导航属性,因此无法用作主键。正如错误消息所暗示的那样:只支持这些数据类型作为主键(可以转换为支持的数据库中的键列),遗憾的是,QuestionModel和QuestionTypeModel都不是这些。 添加Guid键值以匹配QuestionModel和QuestionTypeModel的键列。