Невозможно вставить повторяющийся ключ в объект в методе seed при связывании двух объектов в ассоциации 1 к * - PullRequest
0 голосов
/ 16 октября 2018

Я получаю эту проблему n-й раз за 4 года и никогда не находил объяснения и решения, почему она работает таким образом.

У меня есть 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, я получаю:

Нарушение PRIMARY KEYограничение "PK_dbo.Questions".Невозможно вставить дубликат ключа в объект 'dbo.Questions'.Дубликат значения ключа (c2c6900a-c8a7-4a4b-aa65-79cd0317f9d1).Оператор был прекращен.

Как связать два объекта в ассоциации один ко многим в Entity Framework?

1 Ответ

0 голосов
/ 16 октября 2018

Это связано с известной ошибкой в ​​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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...