Using EF6 against SQL server, when saving a record with a one to zero-or-one relationship, how do the mappings need to be configured in order for the id of the "One"' to be set in the "zero-or-one"
A simple case for this would be:
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public virtual Car Car { get; set; }
}
public class Car
{
public int CarId { get; set; }
public string Make { get; set; }
public int? PersonId { get; set; }
public virtual Person Person { get; set; }
}
With mapping configurations
public class PersonMap : EntityTypeConfiguration<Person>
{
public PersonMap()
{
HasKey(x => x.PersonId);
HasOptional(x => x.Car)
.WithRequired(x => x.Person);
}
}
public class CarMap : EntityTypeConfiguration<Car>
{
public CarMap()
{
HasKey(x => x.CarId);
Property(x => x.Make).IsRequired();
HasRequired(x => x.Person)
.WithOptional(x => x.Car);
}
}
Running a very simple test against any variations of the mappings above always results in the Car
entity having a PersonId
of null
[TestFixture]
public class PersonMappingTest
{
[Test]
public void ItWorks()
{
var person = new Person {Name = "Test person"};
var car = new Car {Person = person, Make = "Ford"};
person.Car = car;
car.Person = person;
using (var cx = new CompWalkContext())
{
cx.Persons.Add(person);
cx.SaveChanges();
}
}
}
-
CarId Make PersonId
----- ---- --------
1 Ford NULL
2 Ford NULL
Is this possible, or does the Person
entity need to be saved prior to adding the Car
?
You don't want the double-mapping, and your keys are a bit gunked up. A car needs a person, so the PersonID would not be nullable, where-as a person may, or may not have a car. if you want the PersonId on Car, it's a 1-0..1 between person and car. From here you set up the HasRequired on the Car WithOptional but you need to tell EF about the key to use. In the DB, PersonID on the Car table needs to be not-nullable.
Then when you go to create a person and car...
Now if you retrieve a car, you can access their .Person. If you retrieve a person that has a car, you can access their .Car.