代码之家  ›  专栏  ›  技术社区  ›  Nguyen Thanh Ha

为什么我们需要避免在ASP中直接使用IQueryable。NET MVC视图?

  •  -1
  • Nguyen Thanh Ha  · 技术社区  · 8 年前

    我被告知从ASP直接引用IQueryable。NETMVC视图是一种糟糕的做法,但我没有找到任何明确的解释。有些人在访问视图中的IQueryable或DbContext时可能会遇到“已释放对象”错误,但这不是我关心的问题。

    下面是我如何实现一个简单的控制器和一个包含用户列表的视图

    public ActionResult Index() 
    {
        return View(db.Users);
    }
    

    在我看来

    @model IEnumerable<User>
    
    <ul>
    @foreach (var user in Model)
    {
        <li>@user.UserName</li>    
    }
    </ul>
    

    有人告诉我应该返回一个“集合对象”,而不是将IQueryable传递给视图。

    public ActionResult Index() 
    {
        return View(db.Users.ToList());
    }
    

    我有点好奇我为什么要这么做。我可以说,后一种方法比我的第一种方法更糟糕,因为数据集在我的应用程序中迭代了两次,首先构造 List 对象 ToList() 方法,其次是 foreach 在我的视图中循环以渲染 <li> 项目。

    因此,这意味着后一种方法必须有一个我还没有发现的更好的点。即使在ASP。NET论坛或Microsoft MSDN网站,他们也提供了后一种方法的示例,但没有给出任何理由,或者我遗漏了什么?

    有人能为我解释一下这些简单的基本内容吗?

    非常感谢。

    1 回复  |  直到 8 年前
        1
  •  4
  •   Igor    8 年前

    如果你通过 IQueryable 您正在创建 leaky abstraction 您可以在视图中移动业务逻辑,而不是严格地呈现业务模型。这是因为 IQueryable(可查询) 尚未对数据库执行,这给视图留下了很多选项,如过滤更多内容或检索其他属性等,这些都应该在控制器中完成(很好 Separation of Concerns ).

    第二点。如果返回的对象太多,以致于在循环中迭代( for / foreach /等等)会导致这样的性能下降,而你有更大的问题,比如如何用HTML发送/呈现你正在构建的巨大列表,这与从数据库中实际检索这样的列表相结合将是瓶颈。

    最后,您需要处理底层的DbContext。当您的控制器被释放时,这可以向您的控制器注册以进行清理,但我可以看到许多程序员忘记这样做,从而留下了开放的数据库连接。