2015-08-28 62 views
0

我似乎無法理解EF如何處理複合鍵。當我嘗試'add-migration Initial'時,下面的代碼返回「屬性'QuestionID'不能用作實體QuestionQuestionTypesModel的關鍵屬性,因爲屬性類型不是有效的鍵類型,只有標量類型,字符串和字節[]是支持的鍵類型。「EF中的複合鍵

我也嘗試設置註釋而不是重寫OnModelCreating。我用[鑰匙,列(訂單= 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 }); 
     } 
} 
+0

什麼是'CModel'中的'A'和'B'? – JotaBe

+0

它們是表A和B的外鍵。 – user1203996

+0

此示例代碼不會編譯。沒有定義'A'和'B',除非你說出他們到底是什麼。請用工作代碼更新您的示例。如果沒有,我會要求結束這個問題。 – JotaBe

回答

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

這將產生同樣的遷移,但使您的數據層清晰。

+0

這解釋了很多。謝謝。你的代碼和解釋非常清楚謝謝! – user1203996

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

QuestionID和QuestionTypeID均爲導航屬性,因此不能被用作主鍵。正如錯誤消息所示:只有這些數據類型被支持作爲主鍵(可以轉換爲支持的數據庫中的鍵列),不幸的是,QuestionModel和QuestionTypeModel都不是這些。 添加Guid鍵值以匹配QuestionModel和QuestionTypeModel的鍵列。