От одного до нуля или с помощью HasForeignKey
У меня две модели:
public class Person
{
public virtual int Id { get; set; }
public virtual Employee Employee { get; set; } // optional
}
public class Employee
{
public virtual int Id { get; set; }
public virtual int PersonId { get; set; }
public virtual Person Person {get; set; } // required
}
public class EmployeeConfiguration : EntityTypeConfiguration<Employee>
{
public EmployeeConfiguration()
{
Property(e=>e.PersonId) // I need this property mapped
.HasColumnName("person_id")
.HasColumnType("int");
}
}
Я хочу сопоставить их, используя свободное отображение. Таблица Employee имеет столбец "person_id", который не имеет значения NULL. Я пробовал следующее:
HasRequired(e => e.Person)
.WithOptional(p => p.Employee)
.Map(m => m.MapKey("person_id"));
Но он терпит неудачу:
System.Data.Entity.ModelConfiguration.ModelValidationException: один или более ошибок проверки были обнаружены во время генерации модели:
person_id: Имя: каждое имя свойства в типе должно быть уникальным. Имущество имя 'person_id' уже определено.
Мне нужно свойство PersonId самостоятельно, так что я в основном хочу:
HasRequired(e => e.Person)
.WithOptional(p => p.Employee)
.HasForeignKey(e => e.PersonId); // there is no such method
Но нет такого метода здесь, как HasForeignKey
Ответы
Ответ 1
ОК, я понял, что вы должны использовать WithMany
(да, не очевидно), чтобы хранить внешний ключ в некотором свойстве:
Property(e => e.PersonId).HasColumnName("person_id");
HasRequired(e => e.Person)
.WithMany()
.HasForeignKey(p => p.PersonId);
Подробнее см. Индивидуальные ассоциации с иностранными ключами. Кстати, это создаст столбец внешнего ключа сотрудника для таблицы person, но нет другого способа иметь свойство навигации и внешний ключ отдельно.
Если вам нужен внешний ключ для чтения, вы можете изменить свойство PersonId на:
public int PersonId { get { return Person.Id; } }
И используйте свое исходное сопоставление
HasRequired(e => e.Person)
.WithOptional(p => p.Employee)
.Map(m => m.MapKey("person_id"));
Ответ 2
На самом деле лучший способ сделать это:
HasKey(e => e.PersonId);
HasRequired(e => e.Person)
.WithOptional(p => p.Employee);
Обратите внимание, что вам больше не нужно свойство Employee.Id
с таким подходом, поскольку оно было излишним с точки зрения отношения 1 к 0 или 1. В первую очередь.