2016-11-04 3 views
0

У меня есть модель Личность и модель Команда. Команда имеет FK для Лица с нулевым TeamleaderId для Person.PersonId и виртуального Лица Teamleader {get; set;}.Ссылочная целостность Нарушение Constraint при обновлении FK

Есть несколько команд, некоторые из которых имеют командующий, а некоторые нет. Теперь я пытаюсь изменить свойство teamleader другому руководителю команды. В SaveChanges я получаю это исключение: «Нарушение ограничения ссылочной целостности произошло: значения (-ы) свойства« Personal.PersonalId »на одном конце отношения не соответствуют значениям свойств« Team.TeamleaderId »on другой конец ».

Teamleader и TeamleaderId соответствуют друг другу, даже сброс идентификатора команды на нуль не работает.

Когда я впервые установил командующий в команде без лидера, все работает. Изменение состава команды больше не работает.

Что я делаю неправильно?

С наилучшими пожеланиями, Mate

EDIT:

Вот модели:

public class Person 
{ 
    [Key] 
    public long PersonId { get; set; } 
    // some other... 
    // optional: List of Teams 
} 

public class Team 
{ 
    [Key] 
    public long TeamId { get; set; } 
    // some other... 

    public long? TeamleaderId { get; set; } 

    [ForeignKey("TeamleaderId")] 
    public virtual Person Teamleader { get; set; } 
} 

Я до сих пор делают некоторые исследования и вернуться ...

Wow! И теперь для некоторых очень странных:

Если я запрашиваю состояние объекта в окне просмотра, состояние «Модифицировано», и запись сохраняется правильно. Если я не запрашиваю состояние объекта, состояние «Без изменений», когда запись приходит в SaveChanges, и ничего не происходит. В данный момент значение AutoDetectChangesEnabled истинно.

Что, черт возьми, это?

+0

Вы изменения 'TeamLeader' свойство или' свойство TeamLeaderId'? Также будет хорошо, если вы разместите образец модели и код, который воспроизводит проблему (т. Е. [Mcve]) –

+0

у вас есть ChangeTracking включен? Вы загружаете Teamleader после извлечения? Правильно ли заданы состояния// id в базе данных? – DevilSuichiro

+0

Я изменяю свойство TeamLeaderId. Свойство навигации имеет значение null. Мы переключили AutoDetectChanges на false, так как это был плохой убийца производительности. Но это, похоже, приводит к решению. В большинстве случаев установка AutoDetectChanges на false работает. Но в этом конкретном случае мы сталкиваемся с проблемами. Я вернусь с дополнительной информацией ... – Mate

ответ

0

Хорошо, все.

Поскольку AutoDetectChangesEnabled = true является убийцей производительности, мы отключили его при повторении через наши объекты базы данных и добавлении/обновлении их в контексте.

Наше переопределение SaveChanges выполняет итерацию через context.ChangeTracker.Entries(). Где (изменено ...). В соответствии с настройкой AutoDetectChangesEnabled метод Entries() вызывает DbContext.ChangeTracker.DetectChanges() или нет - в этом случае: DetectChanges - это NOT.

Теперь мы просто называем DbContext.ChangeTracker.DetectChanges() вручную непосредственно перед перебором DbContext.ChangeTracker.Entries (измененный ...), поэтому

  • ChangeTracker содержит наши измененные записи с правильными значениями.

  • У нас нет утечки производительности на наших собственных итерационных/перечисляющих объектах. (Например: Сохранение слишком большого количества объектов с довольно большим количеством навигационных свойств с глобально активированным AutoDetectChangesEnabled заняло 12 секунд, вызов DetectChanges только в SaveChanges уменьшил до 400 мс!).

Подводя итог: вы можете установить AutoDetectChangesEnabled в значение false, и вы должны это сделать (особенно.если у вас много записей или много свойств навигации/сложных деревьев данных). И в переопределении SaveChanges вызовите context.ChangeTracker.DetectChanges(), и все должно работать нормально.

HTH, Уважение, Mate

Смежные вопросы