【问题标题】:How to use FirstOrDefault inside Include如何在 Include 中使用 FirstOrDefault
【发布时间】:2014-04-21 05:52:25
【问题描述】:

我有两个用于项目和图片的实体。 每个项目可以有多张图片,但我只想在列出项目时返回每个项目的一张图片。

物品类别

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
}

图片类

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
}

控制器

public ActionResult Lager()
{
    var model = _db.Items.Include(b => b.Pictures.FirstOrDefault()).Where(i =>
    i.Status ==  0)

    return View(model);
}

我的控制器收到此错误

包含路径表达式必须引用在类型上定义的导航属性。对引用导航属性使用虚线路径,对集合导航属性使用 Select 运算符。

视图是强类型的

@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>

在我看来,我想将FilepathFilename 结合起来用于img 的src。 但我不知道该怎么做。

【问题讨论】:

    标签: c# asp.net asp.net-mvc linq


    【解决方案1】:

    我假设您正在使用 Linq for Entities。 Include 指定要包含在查询结果中的相关对象。这在选择不直接在您的 Item 实体上的东西时很有用,因为 Linq for Entities 使用延迟加载。我假设您所追求的只是在您的每个项目上选择第一张或默认图片。看起来像这样:

    _db.Items.Where(i => i.Status == 0)
             .Select(i => new { Picture = i.Pictures.FirstOrDefault(), Item = i} )
             .ToList();
    

    更新 正如 Arnold 所提到的,查询实际上是急切地加载第一项。不需要 .Include。

    根据更新后的问题更新 一般来说,最好不要将各种不必要的东西传递给视图。此外,上面的查询在选择中创建了一个无法传递给视图的匿名对象。相反,为您的视图制作一个特定的模型。可能是这样的:

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

    控制器

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

    查看

    @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>
    

    【讨论】:

    • 您甚至不需要Include,因为您急切地获取第一张图片。
    • 我尝试了这段代码,但没有为我工作。也许我没有解释得很好。我编辑了这个问题,现在它包含更多代码。
    • 非常感谢您的宝贵时间。实际上我想避免创建一个特定的模型,而只是因为重用而使用实体模型。但也许最好制作一个特定的模型。
    猜你喜欢
    • 2015-12-02
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    相关资源
    最近更新 更多