Tyler Day
Tyler Day

Reputation: 1718

Entity Framework 6 code first fluent api config for one to one entity relationship

I currently have a one-to-one relationship between 2 entities. The primary entity looks like this:

public class PrimaryEntity
{
   // primary key
   public Guid Id { get; set; }
   // some other properties...
   public RelatedEntity Related { get; set; }
}

And my related entity looks like this:

public class RelatedEntity
{
   // both the primary and foreign key
   public Guid PrimaryEntityId { get; set; }

   // some other properties
}

So my question is, how could this one-to-one relationship be defined using the EF 6 fluent api (can't use annotations)? I've tried many different variations of config settings for this, all with no luck. Is it even possible to define a one sided relationship like this, and have the key names different? Is the fact that my RelatedEntity is using the same property for both primary and foreign keys?

Any help is appreciated.

UPDATE:

I was able to resolve the issue. The culprit was in the constructor of the PrimaryEntity I was setting Related = new RelatedEntity. I guess EF doesn't like this. I found that all 3 answers provided worked pretty much the same otherwise. Thanks for everyone's help.

Upvotes: 0

Views: 802

Answers (3)

Richard France
Richard France

Reputation: 146

public class PrimaryEntity
{
    // primary key
    public Guid Id { get; set; }
    // some other properties...
    public RelatedEntity Related { get; set; }
}
public class RelatedEntity
{
    // both the primary and foreign key
    public Guid PrimaryEntityId { get; set; }

    // some other properties
 }

 //mapping
 //configure the primary key as mentioned above
 modelBuilder.Entity<RelatedEntity>() 
      .HasKey(t => t.PrimaryEntityId );

 modelBuilder.Entity<PrimaryEntity>()
      .HasRequired(p => p.Related )
      .WithRequiredPrincipal(); //empty parenthesis for one sided navigation.

Not tested - off the top of my head...

Upvotes: 1

Deilan
Deilan

Reputation: 4876

In RelatedEntity class you also need to define a navigation property, which points to PrimaryEntity class:

public class RelatedEntity
{
   // both the primary and foreign key
   public Guid PrimaryEntityId { get; set; }

   public PrimaryEntity Primary { get; set; }
   // some other properties
}

Then you may use it to configure your one-to-one relationship in OnModelCreating method of your custom DbContext class:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<RelatedEntity>().HasKey(e => e.PrimaryEntityId);    
    modelBuilder.Entity<RelatedEntity>().HasRequired(re => re.Primary).WithOptional(pe => pe.Related);
}

Note that here RelatedEntity's PrimaryEntityId property is explicitly configured to be a primary key because it's name in your case is out of default primary key naming convention.

And here is a resulting code first migration, which shows that you get exactly what you need:

CreateTable(
    "dbo.PrimaryEntities",
    c => new
        {
            Id = c.Guid(nullable: false),
        })
    .PrimaryKey(t => t.Id);

CreateTable(
    "dbo.RelatedEntities",
    c => new
        {
            PrimaryEntityId = c.Guid(nullable: false),
        })
    .PrimaryKey(t => t.PrimaryEntityId)
    .ForeignKey("dbo.PrimaryEntities", t => t.PrimaryEntityId)
    .Index(t => t.PrimaryEntityId);

Upvotes: 1

Gosia
Gosia

Reputation: 58

Yes you can configure a one-to-one relationship with EF fluent api.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Configure StudentId as PK for StudentAddress
    modelBuilder.Entity<StudentAddress>()
        .HasKey(e => e.StudentId);

    // Configure StudentId as FK for StudentAddress
    modelBuilder.Entity<Student>()
                .HasOptional(s => s.StudentAddress) // Mark StudentAddress is optional for Student
                .WithRequired(ad => ad.Student); // Create inverse relationship

}

Taken from http://www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx

Upvotes: 1

Related Questions