Entity framework Navigation Properties

asp.net-mvc entity-framework navigation-properties

Question

I am currently trying to develop my first .NET MVC application and so learning the main concepts.

In my application I have a table that displays a list of animals from an animals table. In the table I am also trying to display the animal breed, but I am pulling the breed from the Breed table on the foreign key stored in the Animal tableenter image description here

I am currently trying to use a Navigation Property to display the Breed text and not the ID so I altered my Animal model to look like this

public partial class Animal
{
    public int AnimalId { get; set; }
    public Nullable<int> UserId { get; set; }
    public string TagNo { get; set; }
    public Nullable<int> Species { get; set; }
    public Nullable<bool> Sex { get; set; }
    public Nullable<int> AnimalBreed { get; set; }
    public Nullable<System.DateTime> DOB { get; set; }
    public Nullable<int> OwnershipStatus { get; set; }
    public Nullable<System.DateTime> DateAdded { get; set; }
    public Nullable<bool> BornOnFarm { get; set; }

    public virtual Breed Breed { get; set; }
}

And my breed model looks like

public partial class Breed
{
    public int id { get; set; }
    public Nullable<int> SpeciesID { get; set; }
    public string Breed1 { get; set; }
}

In my view I am trying to display the Breeds field from my animal model as shown below, but the breed column is just empty

<td>
  @Html.DisplayFor(modelItem => item.Breed.Breed1)
</td>

Also finally, here is the code that i am using to send the model to the view

List<Animal> Animal1 = (from animals in db.Animals
    where animals.Species == 2 && animals.OwnershipStatus == 1
    && animals.UserId == WebSecurity.CurrentUserId
    select animals).ToList();

return View(Animal1);
1
1
12/11/2014 11:29:36 PM

Popular Answer

First, don't pluralize single items. It creates confusion in your code:

public virtual Breed Breed { get; set; }

-or-

public virtual ICollection<Breed> Breeds { get; set; }

The virtual attribute allows lazy-loading (a query to fetch the breed will be issued the first time you try to access it). You pretty much always want to include virtual with the property so Entity Framework does not unnecessarily issue joins if you don't actually end up using the property. However, in this case, you are, so you'll want to tell EF to eager-load it by including .Include("Breed") in your query. However, that's just for optimization; it's not your problem here.

Your problem here is that Razor doesn't know how to display Breed. It's not a normal type, obviously, because you created it. So, what you really need is to display the actual property on Breed that you want:

@Html.DisplayFor(m => m.Breed.Breed1)

There's an alternate method, but it's more complex and probably overkill for this scenario. If you really want to use Breed directly, then you need to define a display template for Breed. You do that by adding a new folder to Views\Shared named DisplayTemplates. Inside that folder, add a view named Breed.cshtml. The name of the view here corresponds to the class name, not the property name. Inside that view, you'd do something like:

@model Namespace.To.Breed
@Html.DisplayFor(m => m.Breed1)

Then, in your view you could just do:

@Html.DisplayFor(m => m.Breed)

And Razor will use the display template to render the appropriate thing. Like I said, it's overkill for this, but in more complex object rendering, it might come in handy.

4
2/28/2014 4:00:17 PM


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