e-on
e-on

Reputation: 1605

MVC3 model set up - Code First EF

I'm trying to create a list of train journeys (among other things) in MVC, using code first Entity Framework and wondered how I could map foreign keys for the stations. The Journey model/table will have a DepartureStationID and an ArrivalStationID which will be foreign keys linking to one table/model, called Station.

Here is the code for both these models:

public class Station
{        
    public int StationID { get; set; }
    public string StationName { get; set; }
    public string StationLocation { get; set; }
}

public class Journey
{
    public int JourneyID { get; set; }
    public int DepartureID { get; set; }
    public int ArrivalID { get; set; }
    public int OperatorID  { get; set; }
    public string JourneyCode { get; set; }

    public virtual Operator Operator { get; set; }
    public virtual Station DepartureStation { get; set; }   
    public virtual Station ArrivalStation { get; set; }    
}

There is another foreign key value in there, namely Operator and that has mapped successfully, but the departure and arrivals haven't, and return null values in the view: (@Html.DisplayFor(modelItem => item.DepartureStation.StationName).
When I looked in the database, there had been two additional fields created by EF:

DepartureStation_StationID
ArrivalStation_StationID

And the SQL relationship was between the station table and the two fields above, rather than DepartureID and ArrivalID

So, my question is - Do I need to do something different in the model when referencing the same table for two fields? I don't know why those additional fields were added so I presume I've set up the model incorrectly.

Thanks

Upvotes: 0

Views: 487

Answers (2)

Leniency
Leniency

Reputation: 5024

For completeness, here's the same thing with fluent configuration.

public class MyDb : DbContext
{
    public DbSet<Journey> Journeys { get; set; }
    public DbSet<Operator> Operators { get; set; }
    public DbSet<Station> Stations { get; set; }

    protected override void OnModelCreating(DbModelBuilder builder)
    {
        builder.Entity<Journey>()
            .HasRequired(j => j.DepartureStation)
            .WithMany()
            .HasForeignKey(j => j.DepartureID);

        builder.Entity<Journey>()
            .HasRequired(j => j.ArrivalStation)
            .WithMany()
            .HasForeignKey(j => j.ArrivalId);

        // ... Same thing for operator ...

        base.OnModelCreating(builder);
    }
}

Edit: To address your above comment about the cascade delete, you can add .WillCascadeOnDelete(false) after .HasForeignKey() and that might help (although you'll then have to delete Journey records manually)

Upvotes: 3

Haythem Tlili
Haythem Tlili

Reputation: 566

Add the folowing attributes on your navigation properties :

public class Journey
{
    public int JourneyID { get; set; }
    public int DepartureID { get; set; }
    public int ArrivalID { get; set; }
    public int OperatorID  { get; set; }
    public string JourneyCode { get; set; }

    [ForeignKey("OperatorID")]
    public virtual Operator Operator { get; set; }
    [ForeignKey("DepartureID")]
    public virtual Station DepartureStation { get; set; }
    [ForeignKey("ArrivalID")]
    public virtual Station ArrivalStation { get; set; }
}

And of course you need to regenerate your database in order to apply the new configuration.

Hope this will help.

Upvotes: 3

Related Questions