Reputation: 13
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
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
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
Reputation: 4168
If you want to display the plant name, you could directly use:
@Html.DisplayFor(modelItem => item.PlantType.Name)
Upvotes: 0