Reputation: 2002
My domain model has User and Address Class
public User
{
int Id
Address PrimaryAddress
Address SecondaryAddress
and some other Properties
}
Both are optional, but every address must have a user. Codeirst Mapping looks like
modelBuilder.Entity<User>()
.HasOptional(u => u.PrimaryAddress)
.WithRequired()
.WillCascadeOnDelete(false);
modelBuilder.Entity<User>()
.HasOptional(u => u.SecondaryAddress)
.WithRequired()
.WillCascadeOnDelete(false);
But this is not generating desired result. I am expecting two (int, null) columns for User Table pointing to Address Table. And Address table probably having a UserId (Foreign Key, int, not null) column. But with above code The "ID" column of Address acting as PK and FK (pointing back to User table).
Upvotes: 0
Views: 1102
Reputation: 364269
You have mapped one-to-one relation and that is exactly what you see in the database. In short what you want to achieve is not possible this way.
Especially the part where Address
must have a User
cannot work because you have two navigation properties on User
entity which will result in two different FK columns in Address
table and they will have to be nullable otherwise each address will have to be both primary and secondary for some user.
Correct model is mapped with default mapping (no fluent mapping is needed) because it creates user with two FKs to address. Address is in two one-to-many relations with user because indeed in theory you can have multiple users with the same address.
Another options is to model the relation as many-to-many where junction table will be modeled as entity with additional property AddressType
.
If you really want to follow your current model you must use this:
modelBuilder.Entity<User>()
.HasOptional(u => u.PrimaryAddress)
.WithOptionalPrincipal()
.WillCascadeOnDelete(false);
modelBuilder.Entity<User>()
.HasOptional(u => u.SecondaryAddress)
.WithOptionalPrincipal()
.WillCascadeOnDelete(false);
It will create two additional FK columns in Address
table and the relation itself will be one-to-many (one user can have many addresses). The reason is that enforcing one-to-one requires uniqueness of the FK and current EF version doesn't support unique keys. You can add unique constraints on FK columns in post processing (either through custom DB initializer or with EntityFramework.Migrations) but it will result in other problems. Null value is in SQL considered as valid value so if you have unique constraint on nullable column only single record can have null value.
Upvotes: 1