ASP.Net传递对象以查看参数设置为通过匹配ID过滤的另一个对象的列表

时间:2018-03-26 06:33:52

标签: c# asp.net asp.net-mvc entity-framework asp.net-mvc-5

我目前正在ASP.NET中使用Entity Framework,我正在处理两个模型对象,称为“Game”和“Review”。

“评论”有一个名为“GameId”的属性

“游戏”有一个名为“评论”的属性,这是一个ICollection,旨在保存“评论”的集合,其中“GameId”与“游戏”的“Id”匹配。

我在“GamesController”中尝试将“游戏”传递到“详细信息”视图,其中将显示“游戏”的详细信息,包括匹配的“评论”列表。

这是我目前的代码。

///Controller Code///
public ActionResult Details(int? id)
{    
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    Game game = db.Games.Find(id);

    game.Reviews = db.Reviews.ToList().Where(r => r.GameId == game.Id) as ICollection<Review>;

    if (game == null)
    {
        return HttpNotFound();
    }

    return View(game);
}
///End Controller Code///


///View Code///
@model GameReviewApp.Models.Game

//snipped irrelevant code//

@foreach (var item in Model.Reviews)
{
    <p>@item.Content</p>
}

///End View Code///

运行此代码时,当我尝试加载“详细信息”页面并显示“评论”列表时出现以下错误

  

System.NullReferenceException:'对象引用未设置为对象的实例。'

从我所看到的情况来看,在我的LINQ过滤器之后,ICollection没有被填充并且它被保留为空。我已经仔细检查了我的数据库,我知道列表中最后有两个条目是过滤器才能正常工作。有什么建议吗?

3 个答案:

答案 0 :(得分:0)

问题是您正在尝试将LINQ返回的IEnumerable转换为ICollection - 因为转换失败,game.Reviews每次都将为null。

以下代码应该适合您:

public ActionResult Details(int? id)
    {    
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        Game game = db.Games.Find(id);

        if (game == null)
        {
            return HttpNotFound();
        }

        game.Reviews = db.Reviews.Where(r => r.GameId == game.Id).ToList();            

        return View(game);
    }

您可以使用.ToList()代替as ICollection<Review>,这应该可以成功实现您的目标。

我还建议从.ToList()中删除db.Reviews.ToList(),因为它会从数据库中检索每个Review并将它们放入内存中,此处您只需要对Reviews感兴趣且匹配GameId

编辑:如前所述,game的空检查也应在解析对象后立即进行。

答案 1 :(得分:0)

你需要初始化game.Reviews

    objGame.Reviews = new Icollection<Review>();
    //or

    Game objGame= new Game(){
    Reviews=new ICollection<Review>()
    };

答案 2 :(得分:0)

如果游戏和评论定义了正确的关系,它应该已经通过延迟加载加载,你不需要第二个查询。否则只需在此之后进行空检查

Game game = db.Games.Find(id);

if (game != null)
{
    game.Reviews = db.Reviews.Where(r => r.GameId == game.Id).ToList();
}