Below example of one-to-one relationship throws an exception
public class User
{
public int Id { get; set; }
public Address Address { get; set; }
}
public class Address
{
public int Id { get; set; }
public User User { get; set; }
}
Exception says:
Unable to determine the principal end of an association between the
types 'ConsoleApplication1.Address' and 'ConsoleApplication1.User'.
The principal end of this association must be explicitly configured
using either the relationship fluent API or data annotations.
it works if i remove User property from Address but i don't want.
How can i have such a relationship without an exception ?
While the answer provided by Eranga is correct and creates a shared primary key association between User and Address, you might not want to use it due to the limitations this mapping type has.
Here is another way of creating a 1:1 association which is called one-to-one foreign key association:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Address>()
.HasRequired(a => a.User)
.WithOptional(u => u.Address)
.Map(m => m.MapKey("UserId"));
}
EF Code First recognizes this as a 1:1 association hence allowing you to have a bidirectional association between User and Address.
Now all you need to do is to define a Unique Key constraint on the UserId column to make your relationship a true one to one on your database side. One way for doing so is using a Seed method that has been overridden in a custom initializer class:
class DbInitializer : DropCreateDatabaseAlways<Context>
{
protected override void Seed(Context context)
{
context.Database.ExecuteSqlCommand("ALTER TABLE Addresses ADD CONSTRAINT uc_User UNIQUE(UserId)");
}
}
The above code will result in the following schema:
You need to use fluent API to map the relationship as shared primary key.
public class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Address>()
.HasRequired(a => a.User)
.WithOptional(u => u.Address);
}
}