Отношения моделирования проблем в Entity Framework с использованием сначала кода

Я пытаюсь сначала изучить код в Entity Framework, и у меня возникают проблемы с моделированием отношений. Это базовая база данных HR, которая состоит из двух сущностей: сотрудников и отделов.

Сотрудник принадлежит к отделу, и в отделе есть администратор группы и менеджер, которые фактически являются сотрудниками. Я попытался смоделировать это, используя следующее:

EMPLOYEE

public int? DepartmentID { get; set; }
public virtual Department Department { get; set; }

Context:

modelBuilder.Entity<Employee>().HasOptional(x => x.Department);

DEPARTMENT

public class Department
{
    [Required]
    public int DepartmentID { get; set; }

    [Required(ErrorMessage = "The description is required.")]
    public string Description { get; set; }

    public int? ManagerID { get; set; }
    public virtual Employee Manager { get; set; }

    public int? TeamAdministratorID { get; set; }
    public virtual Employee TeamAdministrator { get; set; }
}

Context:

modelBuilder.Entity<Department>().HasOptional(x => x.Manager);
modelBuilder.Entity<Department>().HasOptional(x => x.TeamAdministrator);

Очевидно, я бы хотел, чтобы в таблице отдела было только четыре столбца - DepartmentID, Description, ManagerID и TeamAdministratorID, но для связи создаются дополнительные два, а именно Manager_EmployeeID и Team_Administrator_EmployeeID. Кроме того, в таблице Employee создается столбец Department_DepartmentID для хранения DepartmentID вместо него с использованием столбца DepartmentID, который я указал в сущности.

Что я делаю неправильно? Как мне определить поля и отношения, чтобы код сначала не игнорировал то, что я указываю, и генерировал собственные поля навигации в базе данных?


person MC76    schedule 12.06.2011    source источник


Ответы (2)


Это связано с тем, что конфигурация вашей модели является неполной - вы начали собственное сопоставление с Fluent API, поэтому вы должны сообщить EF, что эти свойства действительно являются FK для отношений. Для использования сотрудниками:

modelBuilder.Entity<Employee>()
            .HasOptional(x => x.Department)
            .WithMany()
            .HasForeignKey(x => x.DepartmentID);

А для использования отдела:

modelBuilder.Entity<Department>()
            .HasOptional(x => x.Manager)
            .WithMany()
            .HasForeignKey(x => x.ManagerID);
modelBuilder.Entity<Department>()
            .HasOptional(x => x.TeamAdministrator);
            .WithMany()
            .HasForeignKey(x => x.TeamAdministratorID);

Кстати. без свойств навигации по коллекции на противоположной стороне отношений будет сложно использовать модель (все WithMany пусты). По крайней мере Department должно иметь:

public virtual ICollection<Employee> Employees { get; set;}

И сопоставление следует изменить на:

modelBuilder.Entity<Employee>()
            .HasOptional(x => x.Department)
            .WithMany(y => y.Employees)
            .HasForeignKey(x => x.DepartmentID);
person Ladislav Mrnka    schedule 12.06.2011
comment
Теперь я вижу, что это написано таким образом, что для меня это имеет гораздо больший смысл. Большое спасибо за это, теперь все работает отлично. - person MC76; 12.06.2011
comment
Кроме того, если вы хотите избежать использования свойств внешнего ключа в своей модели, вы можете использовать .Map (x = ›x.MapKey (ForeignKeyColumnName)) вместо .HasForeignKey (x =› x.ForeignKeyPropertyName) - person danludwig; 09.12.2011

См. Класс вашего сотрудника

EMPLOYEE    
public int? DepartmentID { get; set; }
public virtual Department Department { get; set; }

Чтобы показать связь между сотрудником и отделом, вы использовали идентификаторы и отдела. На самом деле вам нужно сделать это только один раз - через Department. EF по умолчанию ищет свойство ID и связывает за вас два класса. Таким образом, ваши классы должны включать только один идентификатор - идентификатор самого класса. Попробуйте удалить идентификаторы других классов.

person oleksii    schedule 12.06.2011