Pyrphoros
Pyrphoros

Reputation: 13

Code-First generated database different from DbContext Model

I've successfully setup a simple MVC4 internet app that stores model data onto a LocalDb v11.0 SQL server. I generated the database using a code-first approach, however, the Table fields in the database are different than the model database context.

public class Record
{
    public int Id { get; set; }
    public string PlantLocation { get; set; }
    public Plant PlantType { get; set; }
    public string Description { get; set; }
}
public class Plant
{
    public int Id { get; set; }
    public string Name { get; set; }
}
public class RecordContext : DbContext
{
    public DbSet<Record> Records { get; set; }
    public DbSet<Plant> Plants { get; set; }
}

dbo.Records Table 
[Id]            INT            IDENTITY (1, 1) NOT NULL,
[PlantLocation] NVARCHAR (MAX) NULL,
[Description]   NVARCHAR (MAX) NULL,
**[PlantType_Id]  INT            NULL,**

When i pull-up the table data, every field is populated correctly, with the PlantType_ID showing the Id of the selected Plant.

I have tried the following to try an get at the ID but to no avail:

        @Html.DisplayFor(modelItem => item.PlantType.Id)

I'm not getting build errors or runtime errors if anyone is wondering. Any insight is appreciated.

Upvotes: 1

Views: 104

Answers (3)

Sean Kenny
Sean Kenny

Reputation: 1636

Add virtual to the plant property to allow lazyloading:

public virtual Plant PlantType { get; set; }

To avoid N+1 issues, you can instruct EF to bring back the PlantType record as part of the same initial query. Something like:

var record = db.Records.Include("PlantType").First();

We have an extension method to make it a little nicer using lambdas:

var record = c.Records.Include(i => i.PlantType).First();

public static class Extensions
{
    public static IQueryable<T> Include<T, TProperty>(this IQueryable<T> source, Expression<Func<T, TProperty>> path) where T : class
    {
        return System.Data.Entity.DbExtensions.Include(source, path);
    }
}

Edit

Alternatively you could add the following property to the Record model if all you are after is the id:

public int PlantTypeId { get; set; }

Your database structure will largely stay the same (constraint names will change) except now you can change your razor syntax to be:

@Html.DisplayFor(modelItem => item.PlantTypeId)

You do not need to add the include comments now either.

Upvotes: 2

Jalpesh Vadgama
Jalpesh Vadgama

Reputation: 14226

You are using primary key for display for. That's why its not showing as above said you can use display for for plant type name and other fields.

Upvotes: 0

aquaraga
aquaraga

Reputation: 4168

If you want to display the plant name, you could directly use:

@Html.DisplayFor(modelItem => item.PlantType.Name)

Upvotes: 0

Related Questions