我似乎无法理解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 });
}
}
答案 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的键列。