Sam
Sam

Reputation: 5637

Define one-to-one in EF code first with fluent API

I have two code fist POCOs (Appointee and Case):

public class Appointee
{
    public int ID { get; set; }
    public string ProfileID { get; set; }
    public int? CaseID { get; set; }
    public string FistName { get; set; }
    public string LastName { get; set; }
    public DateTime Dob { get; set; }
    public string Ssn { get; set; }
    public string GrantNumber { get; set; }

    public virtual Case Case { get; set; }
} 

public class Case
{
    [Key]
    public int CaseID { get; set; }
    public string ProfileID { get; set; }
    public int PSCStatusID { get; set; }

    public virtual Appointee Appointee { get; set; }
}  

In our terminology Appointee is synonymous with Profile. So the [Key] of our Appointee is ProfileID.

An appointee doesn't have to have a case assigned so I have CaseID set as nullable int - int?.

From this I get the error, something like, EndPoint cannot be determined between Case and Appointee.

I think the problem is in Case. ProfileID, the foreign key to Appointee, is supposed to be the navigation property for the Virtual Appointee Property. But I don't think it understands that the navigation prop is not AppointeeID but is ProfileID instead.

So I put this in the DbContext:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Appointee>().HasKey(a => a.ProfileID);
        modelBuilder.Entity<Case>().HasKey(c => c.CaseID);
        modelBuilder.Entity<Case>().HasRequired(c => c.Appointee);
        modelBuilder.Entity<Appointee>().HasOptional(a => a.Case);
    }

Now I get: Invalid column name 'Appointee_ProfileID'.

How can I set this up correctly.

Upvotes: 1

Views: 69

Answers (1)

Sam
Sam

Reputation: 5637

Finally solved this. A couple of things here. I'm so used to setting up Surrogate Primary Keys with AutoInc that I set up autoinc IDs for Appointee and Case.

Really the Key for Appointee should be ProfileID.

Next, in Entity Framework, a Foreign key in the dependent table has to be the same as the Primary Key in the parent table, which EF refers to as the principle.

So once I got it in my head that my keys are both, PK and FK, going to have to be ProfileID, I made the following fixes.

public class Appointee
{
    [Key]
    public string ProfileID { get; set; }
    public string FistName { get; set; }
    public string LastName { get; set; }
    public DateTime Dob { get; set; }
    public string Ssn { get; set; }
    public string GrantNumber { get; set; }

    public virtual Case Case { get; set; }
}

public class Case
{
    [Key, ForeignKey("Appointee")]
    public string ProfileID { get; set; }
    public int PSCStatusID { get; set; }

    [ForeignKey("ProfileID")]
    public virtual Appointee Appointee { get; set; }
}

Notice the [Key, ForeignKey("Appointee")] attribute on Case which I need to tell EF that Appointee is the principle.

Upvotes: 1

Related Questions