【问题标题】:Why is a new row being added to the foreign key table and not updating the associated row for the entity?为什么将新行添加到外键表中而不更新实体的关联行?
【发布时间】:2013-02-14 17:43:15
【问题描述】:

我可能犯了一个愚蠢的错误,但我不知道为什么会这样。我最初保存个人信息,这会在问题表中创建一行,但是当我去更新问题时,它会在问题表中创建一个新行并将 questionId 列更新为添加的新行。代码如下。

public class PersonalInfo
{
    public virtual int PersonalInfoId { get; set; }

    public virtual string FirstName { get; set; }

    public virtual string LastName { get; set; }

    public virtual string Email { get; set; }

    public virtual string CompanyName { get; set; }

    public virtual string Gender { get; set; }

    public virtual DateTime GenerationDate { get; set; }

    [ForeignKey("Question")]
    public int QuestionId { get; set; }

    [ForeignKey("QuestionId")]
    public virtual Question Question { get; set; }

    public PersonalInfo()
    {
        if (Question == null)
            Question = new Question();
    }
}

public class Question
{
    public virtual int QuestionId { get; set; }
    public virtual string Question1 { get; set; }
    public virtual string Question2 { get; set; }
    public virtual string Question3 { get; set; }
    public virtual string Question4 { get; set; }
    public virtual string Question5 { get; set; }
    public virtual string Question6 { get; set; }
    public virtual string Question7 { get; set; }
    public virtual string Question8 { get; set; }
    public virtual string Question9 { get; set; }
    public virtual string Question10 { get; set; }
    public virtual string Question11 { get; set; }
    public virtual string Question12 { get; set; }
}

还有更新代码...

[HttpPost]
    public ActionResult Questions(FormCollection form)
    {
        int id = GetCookie();

        //var questions = db.Questions.Find(id);
        var personalInfo = db.PersonalInfoes.Include(i => i.Question).SingleOrDefault(p => p.PersonalInfoId == id);

        personalInfo.Question.Question1 = form["question1"];
        personalInfo.Question.Question2 = form["question2"];
        personalInfo.Question.Question3 = form["question3"];
        personalInfo.Question.Question4 = form["question4"];
        personalInfo.Question.Question5 = form["question5"];
        personalInfo.Question.Question6 = form["question6"];
        personalInfo.Question.Question7 = form["question7"];
        personalInfo.Question.Question8 = form["question8"];
        personalInfo.Question.Question9 = form["question9"];
        personalInfo.Question.Question10 = form["question10"];
        personalInfo.Question.Question11 = form["question11"];
        personalInfo.Question.Question12 = form["question12"];

        db.SaveChanges();

        return RedirectToAction("list");   
    }

【问题讨论】:

  • 似乎你不是模型绑定动作方法参数。请在您的帖子中包含您的整个操作方法。
  • 我已经包含了整个动作方法。
  • 在控制器中调试POST动作时,personalInfo.Question.QuestionId的值是多少?
  • 它说的是0,所以显然没有抓取之前创建的行。
  • @DaveA,在同时使用 MVC 和 EF 时,我不止一次遇到过这种情况。现在是我的反应。 :-)

标签: entity-framework asp.net-mvc-4 ef-code-first


【解决方案1】:

尝试注释掉这段代码:

if (Question == null)
    Question = new Question();

更新

定义 2 个外键也可能存在问题

[ForeignKey("Question")]
public int QuestionId { get; set; }

[ForeignKey("QuestionId")]
public virtual Question Question { get; set; }

如错误所示,包括Questions_QuestionId

如果你把它减少到一个条目会发生什么:

[ForeignKey("QuestionId")]
public virtual Question Question { get; set; }

【讨论】:

  • 如果没有我收到此错误,“INSERT 语句与 FOREIGN KEY 约束“FK_dbo.PersonalInfoes_dbo.Questions_QuestionId”冲突。冲突发生在数据库“”,表“dbo.Questions”,列' QuestionId'。该语句已终止。”
  • @stackDat:但是您在 POST 操作中的上述评论中没有收到错误,是吗?当您“最初保存个人信息”时,您会得到它,对吗?当然,当您删除Question = new Question 行时(您必须这样做,这会导致问题),您需要在“初始保存”personalInfo 之前创建一个personalInfo.Question = new Question()
  • 否,当我将个人信息保存在另一个操作方法中时,它保存得很好,并在问题表中创建了一个带有空值的关联行。当我去更新问题时,它不会拉取先前创建的关联行并创建一个新行。我可以做 var questions = db.Questions.Find(id);并保存问题,然后执行 var personalInfo = db.PersonalInfoes.Find(id);获取其他信息,但我认为有某种方法可以让一个组合实体使用。也许我错了。
  • @stackDat:它会创建一个新行,而不是拉取先前创建的行,因为 PersonalInfo 构造函数中有 Question = new Question()。删除它。
  • 太棒了,这毕竟是问题所在。我在某处的一个例子中看到了这一点。不知道为什么人们现在想这样做。谢谢你们!
【解决方案2】:

根据 cmets,personalInfo.Question.QuestionId 为 0 意味着 EF 将查看该问题记录并确定它实际上是一个新记录,并且与前一个记录没有链接。这就是为什么它每次都重新创建行。

您可以采取以下两种解决方案之一:

1) 将 QuestionId 放入会话缓存中,然后在控制器中抓取它,使用它来抓取问题,并在那里进行必要的更新。

2) 将 QuestionId 作为隐藏字段放入 View 中,并确保在提交表单时将其传递到控制器中。从那里抓住问题并进行必要的更新。您甚至可以将该字段设置为可选参数,这样当它为 0 时,您就知道需要创建问题。

【讨论】:

  • 所以我无法在一次查询中获取个人信息和相关问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-30
相关资源
最近更新 更多