Gravy
Gravy

Reputation: 12445

MVC4 Seed Database Foreign Key by Id

I have 2 classes which hold data for restaurants.

Status.cs

public class Status
{

    [Required]
    public int StatusId { get; set; }

    [Required]
    [DisplayName("Status")]
    public string Name { get; set; }
}

Restaurant.cs

public class Restaurant
{
    public int RestaurantId { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    [EmailAddress]
    public string Email { get; set; }

    [Required]
    public string Telephone { get; set; }

    [Required]
    public int StatusId { get; set; }



    // NAVIGATION PROPERTIES

    public virtual Status Status { get; set; }
}

I am trying to seed data into the database.

First, I seed the status table, then I wish to seed the Restaurants table.

var statuses = new List<Status>
{
    new Status { Name = "Draft" },
    new Status { Name = "Live" },
    new Status { Name = "Invisible" },
    new Status { Name = "Discontinued" }
};
statuses.ForEach(a => context.Statuses.Add(a));

var restaurants = new List<Restaurant> 
{ 
    new Restaurant { Name = "The Restaurant Name", Email = "[email protected]", Telephone = "012345566787", StatusId = 1 }
};
restaurants.ForEach(a=>context.Restaurants.Add(a));

base.seed(context);

This doesn't work, because it doesn't like the way I try to seed StatusId = 1 into Restaurant.

I know that I can create a new Status within the new Restaurant, however, I have already seeded the statuses into the database. How do I go about setting the Restaurant's Status to Draft???

Do I have to do this every time???

new Restaurant { Name = "The Restaurant Name", Email = "[email protected]", Telephone = "012345566787", StatusId = new Status { Name = "Draft"} }

Will this not literally generate a new row in the status table called Status every time I create a new Restaurant with the status "Draft"?

Upvotes: 2

Views: 2482

Answers (1)

D Stanley
D Stanley

Reputation: 152521

Don't set the StatusId, set the Status:

var restaurants = new List<Restaurant> 
{ 
    new Restaurant { 
        Name = "The Restaurant Name", 
        Email = "[email protected]", 
        Telephone = "012345566787", 
        Status = statuses.Single(s=>s.Name=="Draft") }
};

That way the StatusID is set by the context and uses the same ID as the Status.

If you want to reference the Status in the list by Index (e.g. statuses[0] for "Draft") that works too; selecting by name is more appropriate, though, IMHO.

EDIT

Just read the end of your question - so to answer that:

When you create a "new" Status and attach it to your Restaurant, the context doesn't know that you want to use the existing status of "Draft", so it does what you tell it - creates a new one. When you attach an existing Status from the context is used that ID since it's the same instance.

Upvotes: 8

Related Questions