Entity Framework Code First initializing foreign keys

c# ef-code-first entity-framework entity-framework-6

Question

This is how the code looks like:

public class Family
{
    public int FamilyID { get; set; }
    public virtual ICollection<Member> FamilyMembers { get; set; }
}
public class Member
{
    public int MemberID { get; set; }
    public virtual Family Family { get; set; }
}
public class Bicycle
{
    public int BicycleID { get; set; }
    public virtual Member Owner { get; set; }
}
public class MyContext : DbContext
{
    public MyContext : base () { }
}

So, there is a one-to-one relantionship between Member and Bicycle, and there is one-to-many relationship between Family and Member. My question is: how do I initialize these foreign keys using my context? All the tutorials on the internet say how to define, but now how to initialize them. Do I simply assign them a correct int value or do I assign them a whole object, and if so, how do I do that? Using LINQ?

@Edit: Assume there are 2 families: Smith and Johnson. Smith has 3 members: Ben, Amy, Brian. Johnson has 2 members: John and Natalie. How do I initialize all that in my code?

1
2
2/26/2016 8:01:25 PM

Accepted Answer

First, fix this:

public class Member
{
    public int MemberID { get; set; }
    public virtual Family Family { get; set; }
}

That should be enough to configure the relationships. EF will make the keys identity by convention.

You can assign the relationships multiple ways. You can explicitly set FK Ids if you add them to your models, or you can use the navigation properties like this:

var family = new Family { LastName = "Smith", ...};
List<Member> members = new List<Member>
{
    new Member(){ Name = "Ben", ... },
    new Member(){ Name = "Amy", ... },
    new Member(){ Name = "Brian", ... }
};
family.FamilyMembers = members;
context.Family.Add(family);
context.SaveChanges();

To assign a bike to an owner:

var owner = context.Members.Find(ownerId);
var bike = new Bicycle
{
    Make = "ACME",
    Model = "XXXX",
    Owner = owner
};
context.Bicycles.Add(bike);
context.SaveChanges();

EDIT: Yes, it is certainly permissible to add FK to your model. That's the method I use. Like this code:

public class Member
{
    public int MemberID { get; set; }
    public int FamilyID { get; set; }  // EF will automatically make this a FK by convention
    public virtual Family Family { get; set; }
}

You need to add annotations if you don't adhere to convention or if you want them for documentation sake:

public class Member
{
    public int MemberID { get; set; }
    public int FamilyID { get; set; }
    [ForeignKey("FamilyID")]
    public virtual Family Family { get; set; }
}

See http://www.entityframeworktutorial.net/code-first/foreignkey-dataannotations-attribute-in-code-first.aspx

I prefer the fluent api. It keeps my models cleaner and separates concerns. For simple projects you can add all the fluent code in the OnModelCreating() override in your context, but I prefer to store my entity configurations in a folder under my context (one file per entity) as described here: http://odetocode.com/blogs/scott/archive/2011/11/28/composing-entity-framework-fluent-configurations.aspx

You can actually have EF automatically find your fluent code using the technique described here: https://msdn.microsoft.com/en-us/magazine/dn519921.aspx

Regarding the child collections, yes, you can new it up in the constructor:

public class Family
{
    public Family()
    {
        FamilyMembers = new HashSet<Member>();
    }

    public int FamilyID { get; set; }
    public virtual ICollection<Member> FamilyMembers { get; set; }
}
2
2/27/2016 4:36:19 PM

Popular Answer

You don't need to explicitly define a foreign key between Family and Member. Entity Framework will take care of this for you if you require. Because you have already stated this property

public virtual ICollection<Member> FamilyMembers { get; set; }

On the Family class the Foreign key is created during the initial Add-Migration or Update-database. So you don't need the property

public virtual FamilyFK { get; set; }


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow