Подтвердить что ты не робот

От одного до нуля или с помощью 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

4b9b3361

Ответ 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. В первую очередь.