Create optional-optional relationship in EF6 with PK instead of FK

Viewed 40

Is it possible to create a mapping which would fill my navigation property automatically, based on table's PK? That means I don't want to have a FK on any table. I know it is possible when there is Optional -> Required mapping. AFAIK no constraint is created on SQL Server, the relationship is "simulated" by EF6 in runtime.

|====================|                   |====================|
|        Car         |                   |       Driver       |
|====================|                   |====================|
|         Id         |  0..1 ----- 0..1  |         Id         |
|--------------------|                   |--------------------|

So that code _dbContext.Cars.Include(x => x.Driver).First(x => x.Id == 1); would return a car with driver if exists, or null driver if doesn't exist.

class Car
{
    public int Id { get; set; }
    public virtual Driver Driver { get; set; }
}

class Driver
{
    public int Id { get; set; }
    public virtual Car Car { get; set; }
}

The following mappings wants to create a DriverId in my Car:

class CarMapping : EntityTypeConfiguration<Car>
{
    public CarMapping()
    {
        HasKey(x => x.Id);
    }
}

class DriverMapping : EntityTypeConfiguration<Driver>
{
    public CarMapping()
    {
        HasKey(x => x.Id);
        HasOptional(x => x.Car)
            .WithOptionalPrincipal(x => x.Driver);
    }
}

EDIT

I checked with mentioned earlier required mapping:

class CarMapping : EntityTypeConfiguration<Car>
{
    public CarMapping()
    {
        HasKey(x => x.Id);
    }
}

class DriverMapping : EntityTypeConfiguration<Driver>
{
    public CarMapping()
    {
        HasKey(x => x.Id);
        HasOptional(x => x.Car)
            .WithRequired(x => x.Driver);
    }
}

And it works. EF6 does not perform any validation on Inserts nor Deletes... Is this a bug? Well at least it works for my case.

1 Answers

As far as I understand you want a one-to-one relationship between a Car and a Driver i.e. each Car can have zero or one driver. If so you need to define the Driver's primary key as a foreign key to the Car's entity. Have you tried this

class Driver
{
   [ForeignKey("Car")]
   public int Id { get; set; }
   public virtual Car Car { get; set; }
}

This way only a Car record will have only one Driver record referencing it at the same time.

Related