Внешний ключ EF с использованием Fluent API

Вот мои модели. У меня есть одно к одному отображение для Vehicle and Driver. Сначала я создам транспортное средство, а затем сопоставьте водителя с транспортным средством.

public class Driver
{
    public int Id { get; set; }
    public String Name { get; set; }
    public int VehicleId { get; set; }
    public virtual Vehicle Vehicle  { get; set; }
}

public class Vehicle
{  
    public int Id { get; set; }
    public String Name { get; set; }

    public virtual Driver Driver { get; set; }

    public int VehicleGroupId { get; set; }
    public virtual VehicleGroup Vehicles { get; set; }
}

Я хочу использовать свойство VehicleId в классе Driver для хранения идентификатора автомобиля, в котором водитель водит.

Я написал следующий код API Fluent:

modelBuilder.Entity<Vehicle>()
            .HasRequired(d => d.Driver)
            .WithRequiredPrincipal();

Но он создает новый столбец в таблице драйверов - Vehicle_VehicleId и сопоставляет его с таблицей VehicleId on Vehicle. Я хочу, чтобы карта VehicleId of Driver отображалась.

Кроме того, я новичок в EF и Fluent API. Я нахожу это чрезвычайно запутанным выбором между WithRequiredDependent и WithRequiredPrincipal. Был бы рад, если бы вы могли описать это простыми словами. Спасибо.

Ответ 1

Эта строка:

public int VehicleId {get; set; задавать; } }

через соглашения о кодировке сообщает EF, что вам нужен внешний ключ в Driver указывающий на Vehicle.

Следующее говорит EF, что вы хотите отношения 1:1 от Driver до Vehicle:

общедоступная виртуальная машина Vehicle {get; set; задавать; } }

Вы должны удалить оба и придерживаться конфигурации Fluent API.

Относительно WithRequiredPrincipal против WithRequiredDependent :

Вы указываете обязательные отношения между Vehicle и Driver при переходе от Vehicle к Driver, таким образом: транспортное средство 1 → 1 Driver

(Транспортное средство является основным, а Driver зависимым, поскольку свойство навигации находится в Vehicle и указывает на Driver.)

modelBuilder.Entity<Vehicle>()
            .HasRequired(d => d.Driver)
            .WithRequiredDependent();

Вы указываете обязательные отношения между Vehicle и Driver при переходе от Driver к Vehicle, таким образом: Vehicle 1 <- 1 Driver

(Vehicle является зависимым, а Driver - главным, так как свойство навигации находится в поле " Driver указывающем на " Vehicle.)

Эти два аналогичны:

modelBuilder.Entity<Vehicle>()
            .HasRequired(v => v.Driver)
            .WithRequiredPrincipal();

modelBuilder.Entity<Driver>()
            .HasRequired(d => d.Vehicle)
            .WithRequiredDependent();

Ответ 2

EF создает столбец Vehicle_VehicleId, потому что у вас есть VehicleId и Vehicle для вашего объекта Driver.

Удалите VehicleId и Vehicle из вашего Driver Entity:

public class Driver
{
    public int Id { get; set; }
    public String Name { get; set; }
}

public class Vehicle
{  
    public int Id { get; set; }
    public String Name { get; set; }
}

Использование:

modelBuilder.Entity<Vehicle>()
        .HasRequired(d => d.Driver)
        .WithRequiredPrincipal();

вы устанавливаете отношения, поэтому не нужно включать свойства вручную в классы сущностей.

Вы получаете VehicleId из свойства навигации Vehicle:

IQueryable<int> vehicleIds = context.Drivers.Select(x => x.Id == 123).Vehicles.Id;