Свойства навигации в EF41 с первым кодом, без внешнего ключа?

#c# #entity-framework #ef-code-first

#c# #entity-framework #ef-code-first

Вопрос:

Возможно ли создать / сопоставить свойства навигации в EF41 с помощью code first, не имея внешнего ключа? В моем случае мне это нужно для историзации:

 public class Person
{
 public virtual Guid ID { get; set; }
 public virtual string Name { get; set; }
 public virtual IList<PersonHist> History { get; set; }
}

public class PersonHist
{
 public virtual Guid ID { get; set; }
 public virtual Guid PersonID { get; set; }
 public virtual string Name { get; set; }
}
  

Представьте: человек был изменен несколько раз, поэтому в Person — одна запись, а в PersonHist — N исторических записей. Теперь я удаляю Person, поэтому у Person не должно быть этого Person, и PersonHist теперь имеет на одну запись больше. Но это невозможно с внешним ключом…
(Мне не нужен удаленный флаг / столбец лично!, но я хочу свойство навигации от человека к PersonHist …)

Ответ №1:

Логика свойств навигации основана на внешних ключах. Итак, если вы хотите сопоставить его и использовать как свойство навигации, у вас должен быть внешний ключ PersonHist . Вы можете сделать ключ обнуляемым, но вам нужно будет правильно его использовать:

  • Измените сопоставление, чтобы удалить каскадное удаление, используемое по умолчанию
  • Установите значение null для всех связанных PersonHist перед удалением Person или внедрите пользовательский инициализатор базы данных и замените ссылочное ограничение на ON DELETE SET NULL

Если вам не нужен внешний ключ, не используйте его в качестве свойства навигации и используйте отдельный запрос для получения исторических записей для person — но для этого все равно потребуется некоторый столбец, указывающий на исходную Person запись.