IT:AD:Code First:Entities:Relationships:1-1
Situation
Sitauation
- You have an Invoice and a User and Address.
- You want a 1-1..0 relationship between User and Address.
- You want a Refererence Navigation Property from User to Address
- You do not want a Reference Navigation Property from Address back to User
- As it's not a 1-1 relationship there's no reason to tie the two id's together.
And:
- You've been banging away for hours and your head is done in.
Solution
It depends what you need…
If you want each table to have it's own independent life/id, then the answer is not:
modelBuilder.Entity<User>() .HasRequired(i => i.BillingAddress) .WithOptional(); //1-0...1 //.HasForeignKey(cp => cp.BillingAddressId) //(optional) //.WillCascadeOnDelete(true|false); //(optional)
It fails with Address getting an PK with IDENTITY specified, but User, not, so when inserting new Users, fails, asking for an Id to be set.
The Solution is explained here and then building on that here
Specifically:
You cannot create an one-to-one relationship with a foreign key property which is not the primary key property at the same time. EF supports only Shared Primary Key Associations to define a one-to-one relationship.
In other words, the code is creating an FK db relationship where User.Id is PK to User Table AND FK to Address.Id at the same time, resulting in Db table having only one UserId Column (no AddressFK column).
The end result is one can have:
* an Address with no User.
* An address with a User, but if it does, there can be only one (as it's ID is the FK, and it also is the ID of the other column…which is used)…phew.
So if you need both tables to have their own Id, independently, you designate it as follows:
modelBuilder.Entity<User>() .HasRequired(i => i.BillingAddress) .WithMany(); //for 1-0...n //.HasForeignKey(cp => cp.BillingAddressId) //(optional) //.WillCascadeOnDelete(true|false) //(optional)
The above ensures the User table gets it's own Id and an AddressId column.