I have achieved a 1:0-1 association between two entities, Person and User. The requirement, a User must have one and only one Person; while a Person may or may not be associated with a User.
public class Person
{
public int PersonId { get; set; }
public virtual User User { get; set; }
}
public class User
{
public int UserId { get; set; }
public int PersonId { get; set; }
public virtual Person Person { get; set; }
}
Define EntityTypeConfiguration classes as follows and include them in the DbContext OnModelCreating method.
public class PersonConfiguration : EntityTypeConfiguration<Person>
{
public PersonConfiguration()
{
ToTable("People");
HasKey(p => p.PersonId);
Property(p => p.PersonId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasOptional(p => p.User).WithRequired(u => u.Person); // User is option here but
// Person is required in User
}
}
public class UserConfiguration : EntityTypeConfiguration<User>
{
public UserConfiguration()
{
ToTable("Users");
HasKey(u => u.UserId);
Property(u => u.UserId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
// Create a unique index in the Users table on PersonId
Property(u => u.PersonId).IsRequired().HasColumnAnnotation("Index",
new IndexAnnotation(new IndexAttribute("IX_PersonId") { IsUnique = true }));
}
}
Put the following lines in the DbContext.OnModelCreating method.
modelBuilder.Configurations.Add(new PersonConfiguration());
modelBuilder.Configurations.Add(new UserConfiguration());
Run an Add-Migration command and you will get something like the following in the DbMigration,Up method. Make changes as follows.
CreateTable(
"dbo.Users",
c => new
{
Id = c.String(nullable: false, maxLength: 128),
PersonId = c.Int(nullable: false),
Person_PersonId = c.Int(nullable: false), // Delete this
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.People", t => t.Person_PersonId) // change to .ForeignKey("dbo.People", t => t.PersonId)
.Index(t => t.PersonId, unique: true) // append a ';'
.Index(t => t._Person_PersonId); // Delete this
CreateTable(
"dbo.People",
c => new
{
PersonId = c.Int(nullable: false, identity: true),
})
.PrimaryKey(t => t.PersonId)
Modify the Down() method as follows.
Change
DropForeignKey("dbo.Users", "Person_PersonId", "dbo.People");
to
DropForeignKey("dbo.AppUsers", "PersonId", "dbo.People");
Change
DropIndex("dbo.AppUsers", new[] { "Person_PersonId" });
to
DropIndex("dbo.AppUsers", new[] { "PersonId" });
Run the Update-Database command targeting this migration. The resulting Users and People tables will have a one-to-one association on the PersonId foreign key.