将两个1中的对象链接到*关联

时间:2018-10-16 19:15:53

标签: .net entity-framework

我在4年内第n次遇到此问题,但从未找到解释和解决方案的理由。

我有2节课:

public class Question
{
    public Guid Id { get; set; }
    public String Text { get; set; }
    public virtual Survey Survey { get; set; }
    public virtual List<Answer> Answers { get; set; }
}
public class Answer
{
    public Guid Id { get; set; }
    public String Text { get; set; }
    public virtual Question Question { get; set; }
}

然后在Seed方法中,我想创建问题和答案并将其链接在一起:

        Guid guid23 = new Guid("c2c6900a-c8a7-4a4b-aa65-79cd0317f9d1");
        //some other guids ...
Survey survey1 = new Survey { Id = guid21, Title = "Cars" };
        Survey survey2 = new Survey { Id = guid22, Title = "Phones" };

        Question question1 = new Question { Id = guid23, Text = "What type of car do you have?" };
        Question question2 = new Question { Id = guid24, Text = "What size is the engine?" };
        Question question3 = new Question { Id = guid25, Text = "What phone do you have?" };
        Question question4 = new Question { Id = guid26, Text = "What big is the screen?" };

        Answer answer1 = new Answer { Id = guid27, Text = "Sedan"};
        Answer answer2 = new Answer { Id = guid28, Text = "3000" };


        context.Questions.AddOrUpdate(a => a.Id, question1, question2, question3, question4);
        context.Answers.AddOrUpdate(a => a.Id, answer1, answer2);
        context.SaveChanges();
        context.Answers.Find(answer1.Id).Question = question1;
        context.Answers.Find(answer2.Id).Question = question2;
        context.SaveChanges();

然后,当我运行database update -v时,我得到:

  

违反主键约束'PK_dbo.Questions'。无法插入   对象“ dbo.Questions”中的重复键。重复的键值为   (c2c6900a-c8a7-4a4b-aa65-79cd0317f9d1)。该声明已经   终止。

如何在实体框架中以一对多关联链接两个对象?

1 个答案:

答案 0 :(得分:1)

这是由于known bug in AddOrUpdate引起的。这就是发生的情况。

开始的情况是您已经在数据库中找到了问题和答案。

第一个AddOrUpdate ...

context.Questions.AddOrUpdate(a => a.Id, question1, question2,...

...找到问题并将其附加为上下文UnChanged。但是,实际找到的实例与question1, question2,...不同。找到的实例是隐藏在上下文中的新对象。实例question1, question2,...Detached

因此,声明...

context.Answers.Find(answer1.Id).Question = question1;

...将answer1连接到对上下文来说是全新的问题实例。在语句question1的状态为Added之后,SaveChanges将尝试在现有Id下插入一个新问题。

您已经快解决了。您似乎已经在某种程度上意识到了这个问题,因为您已经在使用context.Answers.Find(answer1.Id)。该语句从上下文的缓存中拉出隐藏的answer1副本,因此EF不会将那个看成是新的。解决方法是对以下问题执行相同的操作:

question1 = context.Questions.Find(question1.Id);
question2 = context.Questions.Find(question2.Id);

context.Answers.Find(answer1.Id).Question = question1;
context.Answers.Find(answer2.Id).Question = question2;
context.SaveChanges();