EF Code First - 1-to-1 Optional Relationship
Asked Answered
S

1

29

I want to map an optional 1-to-1 relationship in an existing database with EF Code First.

Simple schema:

User
 Username
 ContactID

Contact
 ID
 Name

Obviously ContactID joins to Contact.ID. The ContactID field is nullable so the relationship is optional - 0 or 1, never many.

So how do I specify this relationship in EF Code First, with this existing schema?

Here's what I've tried so far:

public class User
{
    [Key]
    public string Username { get; set; }
    public int? ContactID { get; set; }

    [ForeignKey("ContactID")]
    public virtual Contact Contact { get; set; }
}

public class Contact
{
    [Key]
    public int ID { get; set; }
    public string Name { get; set; }

    public virtual User User { get; set; }
}

modelBuilder.Entity<User>().HasOptional<Contact>(u=> u.Contact)
    .WithOptionalDependent(c => c.User);

I get the following Exception:

  System.Data.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role
 'User_Contact_Source' in relationship 'User_Contact'. Because the Dependent 
Role properties are not the key properties, the upper bound of the multiplicity 
of the Dependent Role must be *.
Salzhauer answered 16/5, 2011 at 17:36 Comment(0)
B
44

One solution would be;

public class User
{
    [Key]
    public string Username { get; set; }

    public virtual Contact Contact { get; set; }
}

public class Contact
{
    [Key]
    public int ID { get; set; }
    public string Name { get; set; }

    public virtual User User { get; set; }
}

        modelBuilder.Entity<User>()
            .HasOptional<Contact>(u => u.Contact)
            .WithOptionalDependent(c => c.User).Map(p => p.MapKey("ContactID"));

You set only your navigational objects in your POCOs and instead you use fluent API to map your key to the correct column.

Bleacher answered 16/5, 2011 at 22:7 Comment(5)
This helped me to resolve the following when trying to configure a 0:1 to 0:1 - The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.Chasechaser
I recommend you do include the foreign key property as per the convention (msdn.microsoft.com/en-us/data/jj679962). If whenever you create relationships between entities, do it via this key property rather than the entity property. I've found this way your less likely to get certain exceptions like duplicate keys in the object state manager and more meaningful exceptions when updates go wrong.Cavort
How can I ALSO use a ContactId field in User? If I use the above code and define a ContactId field in User it gives me an error saying it's a duplicate property. How can I tell entity framework that tha column defined with MapKey and the ContactId defined in User are the same.Kicker
Hi @gyozokudor did you find a way to have the ContactId field too? thanks.Constituency
I would use a FK ContactId. See here: entityframeworktutorial.net/code-first/…Lingam

© 2022 - 2024 — McMap. All rights reserved.