简体   繁体   中英

Optional 1:1 relationship in Entity Framework Code First

I'm trying to create what I think would be either called an optional 1:1 or possibly 0..1:0..1 relationship in Entity Framework. I want to be able to have navigation properties on both objects.

I am using Entity Framework's Fluent API over an existing database schema.

For simplicity, lets assume the following tables:

Car
    Id int not null

Driver
    Id int not null
    CarId int null unique

Using the following classes:

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

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

The idea is a Car and a Driver can exist independent of one another, but when a Driver gets associated with a Car it is a mutually exclusive association: the Driver can only be associated with that Car and that Car can only be associated to that Driver.

I tried the following fluent configuration:

Inside Driver's Configuration:

HasOptional(d => d.Car)
    .WithOptionalDependent()
    .Map(d => d.MapKey("CarId"));

And inside the Car configuration

HasOptional(c => cDriver)
    .WithOptionalPrincipal()
    .Map(d => d.MapKey("CarId"));

When I try this I get the following:

Schema specified is not valid. Errors: (203,6) : error 0019: Each property name in a type must be unique. Property name 'CarId' was already defined.

Is there a way to model this scenario with navigation properties on both objects in Entity Framework?

You can do this without Fluent API:

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

    public string Name { get; set; }

    public int? DriverId { get; set; }

    [ForeignKey("DriverId")]
    public virtual Driver Driver { get; set; }
}

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

    public string Name { get; set; }

    public virtual ICollection<Car> Cars { get; set; }
}

Then you need to check if the Driver already has a car, to guarantee that he can have only one.

You don't need to set it up in both fluent classes. I'm surprised that is the error that you received, and not that the relationship is already set up.

Your Drive class will need the CarId as part of the class:

public class Driver 
{
    public int Id { get; set; }
    // Make this int? if a Driver can exist without a Car
    public int CarId { get; set; }
    public virtual Car { get; set; }
}

Then you just need this in the Fluent Config file for Driver, and nothing in the one for Car.

HasOptional(d => d.Car)
    .WithOptionalDependent()
    .Map(d => d.MapKey("CarId"));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM