首页 > 解决方案 > 实体类型“X”的属性“XID”是键的一部分,因此无法修改

问题描述

在新的 Blazor 项目中使用 EF-Core Code First。这是我第一次使用 EF 的核心版本,所以也许我错过了一些新的东西?

我有三个表/模型 - Questions、QuestionOptions 和 QuestionAnswers。QuestionOptions 与 Questions 和 Answers 表相关,因为每个问题可以有多个选项,并且 Answer 表可以存储 QuestionOptions 之一。

public class Question
{
    public int QuestionId { get; set; }
    public string QuestionText { get; set; }
    public bool Active { get; set; }
    public bool Required { get; set; }
    public bool AskToExplain { get; set; }
    public string TextToAskToExplain { get; set; } 

    public virtual int QuestionTypeId { get; set; }
    public virtual QuestionType QuestionType { get; set; }

    public virtual ICollection<QuestionOption> QuestionOptions { get; set; }

    public virtual ICollection<QuestionAnswer> QuestionAnswers { get; set; }
}

public class QuestionOption
{
    public int QuestionOptionId { get; set; }
    public string OptionText { get; set; }

    public virtual int QuestionId { get; set; }
    public virtual Question Question { get; set; }

    public virtual ICollection<QuestionAnswer> QuestionAnswers { get; set; }
}

public class QuestionAnswer
{
    public int QuestionAnswerId { get; set; }
    public string AnswerText { get; set; }

    public virtual int? QuestionOptionId { get; set; }
    public virtual QuestionOption? QuestionOption { get; set; }        

    public virtual int QuestionId { get; set; }
    public virtual Question Question { get; set; }

    public virtual int ProfileID { get; set; }
    public virtual Profile Profile { get; set; }
}

在 QuestionAnswers 表中插入一行可以正常工作,但更新会引发此错误:

实体类型“QuestionOption”上的属性“QuestionOptionId”是键的一部分,因此不能修改或标记为已修改。要使用标识外键更改现有实体的主体,首先删除依赖项并调用“SaveChanges”,然后将依赖项与新主体关联。

    public QuestionAnswer SaveAnswer(QuestionAnswer answer)
    {
        var chosenOption = _db.QuestionOptions.Find(answer.QuestionOptionId);
        var profile = _db.Profiles.Find(answer.Profile.ProfileID);
        var question = _db.Questions.Find(answer.Question.QuestionId);

        if (answer.QuestionAnswerId == 0)
        {   //this works fine...
            var newAnswer = new QuestionAnswer()
            {
                AnswerText = answer.AnswerText,
                QuestionOption = chosenOption,
                Profile = profile,
                Question = question
            };

            var addedEntity = _db.QuestionAnswers.Add(newAnswer);
            _db.SaveChanges();
            return addedEntity.Entity;
        }
        else
        {
            // This is where the error happens...
            var existingAnswer = _db.QuestionAnswers.Find(answer.QuestionAnswerId);
            existingAnswer.AnswerText = answer.AnswerText;
            existingAnswer.QuestionOption = chosenOption;
            _db.SaveChanges(); //<-- Error thrown here
            return existingAnswer;
        }
    }

错误消息听起来像是我正在尝试更改 QuestionOption 的主键,但实际上我只是在尝试更改 QuestionAnswer 指向的 QuestionOption。我只是希望它基本上运行这个 SQL:

 UPDATE QuestionAnswer
 SET AnswerText = @NewAnswerText, QuestionOptionId = @NewQuestionOptionId
 WHERE QuestionAnswerId = @QuestionAnswerId

我究竟做错了什么?

提前感谢您的帮助。

标签: entity-frameworkentity-framework-coreef-core-3.0

解决方案


不能保证,但您可以尝试设置 FK existingAnswer.QuestionOptionId = answer.QuestionOptionId 而不是设置相关实体​​。这就是您将在数据库中执行的操作。


推荐阅读