实体框架 6 映射外键问题

我有 3 个实体:问题


public enum QuestionType

{

    Scenario,

    Step

}


public class Question

{

    public int Id { get; set; }

    public int CategoryId { get; set; }

    [Required] [MaxLength(255)] public string Text { get; set; }

    [MaxLength(255)] public string FrameText { get; set; }

    public int Order { get; set; }

    public QuestionType Type { get; set; }


    public DefaultAnswer DefaultAnswer { get; set; }

    public IList<Answer> Answers { get; set; }

}

回答


public class Answer

{

    public int Id { get; set; }

    public int QuestionId { get; set; }

    [Required] [MaxLength(255)] public string Text { get; set; }

    public int Order { get; set; }


    public Scenario Scenario { get; set; }

    public IList<Formula> Formulas { get; set; }

    public IList<Image> Images { get; set; }

}

最后,DefaultAnswer:


public class DefaultAnswer

{

    public int QuestionId { get; set; }

    public int AnswerId { get; set; }


    public Answer Answer { get; set; }

    public Question Question { get; set; }

}

之间的关系问题和答案是显而易见的。我想为一个问题设置一个DefaultAnswer,所以我DefaultAnswer在Question模型中添加了一个导航属性。这是可选的,因为它可以为空。


所以,我试图建立这样的关系:


modelBuilder.Entity<DefaultAnswer>().HasKey(m => new { m.QuestionId, m.AnswerId });

modelBuilder.Entity<Question>().HasOptional(m => m.DefaultAnswer).WithRequired(m => m.Question);

modelBuilder.Entity<DefaultAnswer>().HasRequired(m => m.Answer).WithMany().HasForeignKey(m => m.AnswerId);

但这不起作用,它会Question_Id在DefaultAnswers表中创建另一个名为的字段..... 这就是 EF 生成的内容:


public override void Up()

{

    CreateTable(

        "dbo.DefaultAnswers",

        c => new

            {

                QuestionId = c.Int(nullable: false),

                AnswerId = c.Int(nullable: false),

                Question_Id = c.Int(nullable: false),

            })

        .PrimaryKey(t => new { t.QuestionId, t.AnswerId })

        .ForeignKey("dbo.Answers", t => t.AnswerId, cascadeDelete: true)

        .ForeignKey("dbo.Questions", t => t.Question_Id)

        .Index(t => t.AnswerId)

        .Index(t => t.Question_Id);


}


有谁知道我如何创建这种关系,同时仍将导航属性保留在Question 中?


茅侃侃
浏览 166回答 2
2回答

慕妹3146593

我不确定引入 DefaultAnswer 实体的意图是什么。但是这种关系可以在没有它的情况下建模。例如:public enum QuestionType{&nbsp; &nbsp; Scenario,&nbsp; &nbsp; Step}public class Question{&nbsp; &nbsp; public int Id { get; set; }&nbsp; &nbsp; public int CategoryId { get; set; }&nbsp; &nbsp; [Required] [MaxLength(255)] public string Text { get; set; }&nbsp; &nbsp; [MaxLength(255)] public string FrameText { get; set; }&nbsp; &nbsp; public int Order { get; set; }&nbsp; &nbsp; public QuestionType Type { get; set; }&nbsp; &nbsp; public int? DefaultAnswerId { get; set; }&nbsp; &nbsp; [ForeignKey("Id,DefaultAnswerId")]&nbsp; &nbsp; public Answer DefaultAnswer { get; set; }&nbsp; &nbsp; public IList<Answer> Answers { get; set; }}public class Answer{&nbsp; &nbsp; public int Id { get; set; }&nbsp; &nbsp; public int QuestionId { get; set; }&nbsp; &nbsp; [Required] [MaxLength(255)] public string Text { get; set; }&nbsp; &nbsp; public int Order { get; set; }&nbsp; &nbsp; public virtual Question Question { get; set; }&nbsp; &nbsp; //public Scenario Scenario { get; set; }&nbsp; &nbsp; //public IList<Formula> Formulas { get; set; }&nbsp; &nbsp; //public IList<Image> Images { get; set; }}class Db: DbContext{&nbsp; &nbsp; public DbSet<Question> Question { get; set; }&nbsp; &nbsp; public DbSet<Answer> Answer { get; set; }&nbsp; &nbsp; protected override void OnModelCreating(DbModelBuilder modelBuilder)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; base.OnModelCreating(modelBuilder);&nbsp; &nbsp; &nbsp; &nbsp; modelBuilder.Entity<Answer>().HasKey(m => new { m.QuestionId, m.Id });&nbsp; &nbsp; &nbsp; &nbsp; modelBuilder.Entity<Answer>().HasRequired(m => m.Question).WithMany(q => q.Answers).HasForeignKey( m => m.QuestionId);&nbsp; &nbsp; &nbsp; &nbsp; modelBuilder.Entity<Question>().HasOptional(m => m.DefaultAnswer);&nbsp; &nbsp; }}

料青山看我应如是

首先,建议简单地将答案标记为“默认”的评论听起来不错,但试图帮助解决实际问题......好的,我认为可以为您提供所需的编辑....所以,我在这里使用的模型:public enum QuestionType{&nbsp; &nbsp; Scenario,&nbsp; &nbsp; Step}public class Question{&nbsp; &nbsp; public int Id { get; set; }&nbsp; &nbsp; public int CategoryId { get; set; }&nbsp; &nbsp; [Required] [MaxLength(255)]&nbsp; &nbsp; public string Text { get; set; }&nbsp; &nbsp; [MaxLength(255)]&nbsp; &nbsp; public string FrameText { get; set; }&nbsp; &nbsp; public int Order { get; set; }&nbsp; &nbsp; public QuestionType Type { get; set; }&nbsp; &nbsp; public DefaultAnswer DefaultAnswer { get; set; }&nbsp; &nbsp; public IList<Answer> Answers { get; set; }}public class Answer{&nbsp; &nbsp; public int Id { get; set; }&nbsp; &nbsp; public int QuestionId { get; set; }&nbsp; &nbsp; [Required]&nbsp; &nbsp; [MaxLength(255)]&nbsp; &nbsp; public string Text { get; set; }&nbsp; &nbsp; public int Order { get; set; }&nbsp; &nbsp; public Scenario Scenario { get; set; }&nbsp; &nbsp; public Question Question { get; set; }&nbsp; &nbsp; //commented these out for the sake of this&nbsp; &nbsp; //example&nbsp; &nbsp;/*public IList<Formula> Formulas { get; set; }&nbsp; &nbsp; public IList<Image> Images { get; set; }*/}public class DefaultAnswer{&nbsp; &nbsp; public int QuestionId { get; set; }&nbsp; &nbsp; public int AnswerId { get; set; }&nbsp; &nbsp; public Answer Answer { get; set; }&nbsp; &nbsp; public Question Question { get; set; }}如此定义的关系://don't need a compound key for answers...&nbsp;//easier to just let each answer be entirely unique.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;modelBuilder.Entity<Answer>().HasKey(m => m.Id );modelBuilder.Entity<Answer>().HasRequired(m => m.Question)&nbsp; &nbsp; .WithMany(q => q.Answers).HasForeignKey(m => m.QuestionId);modelBuilder.Entity<Question>()&nbsp; &nbsp; .HasOptional(m => m.DefaultAnswer)&nbsp; &nbsp; .WithOptionalDependent(m => m.Question);//default answer is basically a mapping table between questions and answers.//so it has a compound key.&nbsp; In fact the table should consist of ONLY these two key//fields...modelBuilder.Entity<DefaultAnswer>()&nbsp; &nbsp; .HasKey(m => new { m.AnswerId, m.QuestionId });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;这为我产生了这个:CreateTable(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "dbo.DefaultAnswers",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c => new&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AnswerId = c.Int(nullable: false),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; QuestionId = c.Int(nullable: false),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .PrimaryKey(t => new { t.AnswerId, t.QuestionId })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .ForeignKey("dbo.Answers", t => t.AnswerId, cascadeDelete: true)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Index(t => t.AnswerId);唯一让我无法理解的是级联删除行为是如何设置的......有点担心删除“DefaultAnswer”记录会删除答案 - 当天太晚了,我的大脑无法解决这个问题我'我害怕!
打开App,查看更多内容
随时随地看视频慕课网APP