I have two entities for items and pictures. Each item can have multiple pictures, but I only want to return one picture of each item when I list the items.
Item class
public class Item
{
[Key]
public int ItemID { get; set; }
public string Name{ get; set; }
public string Status{ get; set; }
public virtual ICollection<Picture> Pictures{ get; set; } // Navigation property
}
Picture class
public class Picture
{
[Key]
public int PictureID { get; set; }
public string Filename{ get; set; }
public string Filepath{ get; set; }
public int ItemID { get; set; } // Foreign Key
public virtual Item Item{ get; set; } // Navigation property
}
Controller
public ActionResult Lager()
{
var model = _db.Items.Include(b => b.Pictures.FirstOrDefault()).Where(i =>
i.Status == 0)
return View(model);
}
I get this error from my controller
The Include path expression must refer to a navigation property defined on the type. Use dotted paths for reference navigation properties and the Select operator for collection navigation properties.
The view is strongly typed
@model IEnumerable<MyProject.Models.Koeretoej>
<div">
@foreach(var item in Model){
<ul>
<li>
<span class="icon">
<img src="@item.Pictures.Filepath@item.Billeder.Filepath"/>
</span>
</li>
<li><span class="text">@item.Name</span></li>
<li><span class="text">@item.Status</span></li>
</ul>
}
</div>
And in my view I want to combine Filepath
and Filename
to use it for the img
's src. But I'm not sure how to do it.
I assume your are using Linq for Entities. Include specifies the related objects to include in the query results. This is useful when selecting something that is not directly on your Item entity, as Linq for Entities uses lazy loading. What i assume you are after, is only Selecting the first or default Picture on each of your Item. That would look something like this:
_db.Items.Where(i => i.Status == 0)
.Select(i => new { Picture = i.Pictures.FirstOrDefault(), Item = i} )
.ToList();
Update As mentioned by Arnold, the query is actually eager loading the first item. There is no need for .Include.
Update according to updated question Generally, it's better design to not pass all kinds of unnecessary thing to the view. Also, the query above creates an anonymous object in the select, that can't be passed to a view. Instead, make a specific model for your view. Perhaps like this:
ItemWithPicture.cs
public class ItemWithPicture
{
public int ItemID { get; set; }
public string Name{ get; set; }
public string Status{ get; set; }
public string PictureFilename{ get; set; }
public string PictureFilepath{ get; set; }
}
Controller
public ActionResult Lager()
{
var model = _db.Items.Where(i => i.Status == 0).Select(i => new { Picture = i.Pictures.FirstOrDefault(), Item = i} ).Select(i => new {
ItemID = i.Item.ItemID,
Name = i.Item.Name,
Status = i.Item.Status,
PictureFilename = i.Picture != null ? i.Picture.Filename : null,
PictureFilepath = i.Picture != null ? i.Picture.Filepath : null
}).ToList();
return View(model);
}
View
@model IEnumerable<SomeNamespace.ItemWithPicture>
<div>
@foreach(var item in Model){
<ul>
<li>
<span class="icon">
<img src="@item.Filepath"/>
</span>
</li>
<li><span class="text">@item.Name</span></li>
<li><span class="text">@item.Status</span></li>
</ul>
}
</div>
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.