In the last example, you can see that EF figures out which column is the foreign key and where should it point to. How? By using conventions. Having a property of type Person
that is named Person
with a PersonId
property leads EF to conclude that PersonId
is a foreign key, and it points to the primary key of the table represented by the type Person
.
But what if you were to change PersonId to OwnerId and Person to Owner in the Car type?
public class Car { public int CarId { get; set; } public string LicensePlate { get; set; } public int OwnerId { get; set; } public virtual Person Owner { get; set; } }
Well, unfortunately in this case, the conventions are not enough to produce the correct DB schema:
No worries; you can help EF with some hints about your relationships and keys in the model. Simply configure your Car
type to use the OwnerId
property as the FK. Create an entity type configuration and apply it in your OnModelCreating()
:
public class CarEntityTypeConfiguration : EntityTypeConfiguration<Car>
{
public CarEntityTypeConfiguration()
{
this.HasRequired(c => c.Owner).WithMany(p => p.Cars).HasForeignKey(c => c.OwnerId);
}
}
This basically says that Car
has a required property, Owner
(HasRequired()) and in the type of Owner
, the Cars
property is used to refer back to the car entities (WithMany()). And finally the property representing the foreign key is specified (HasForeignKey()). This gives us the schema we want:
You could configure the relationship from the Person
side as well:
public class PersonEntityTypeConfiguration : EntityTypeConfiguration<Person>
{
public PersonEntityTypeConfiguration()
{
this.HasMany(p => p.Cars).WithRequired(c => c.Owner).HasForeignKey(c => c.OwnerId);
}
}
The idea is the same, just the sides are different (note how you can read the whole thing: 'this person has many cars, each car with a required owner'). Doesn't matter if you configure the relationship from the Person
side or the Car
side. You can even include both, but in this case be careful to specify the same relationship on both sides!