简体   繁体   中英

Entity framework Navigation Properties

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 table 在此处输入图片说明

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);

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.

If lazy loading is not enabled in your DbContext , then you have to explicitly load (or use eager loading) the navigation properties.

See http://msdn.microsoft.com/en-us/data/jj574232.aspx

You'll end-up with something like:

var res = (from animals in db.Animals.Include("Breeds")
                                    where animals.Species == 2 & animals.OwnershipStatus == 1
                                    & animals.UserId == WebSecurity.CurrentUserId
                                    select animals).ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM