Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将查询结果传递给视图的最佳实践?_C#_Asp.net Mvc_Asp.net Mvc 5 - Fatal编程技术网

C# 将查询结果传递给视图的最佳实践?

C# 将查询结果传递给视图的最佳实践?,c#,asp.net-mvc,asp.net-mvc-5,C#,Asp.net Mvc,Asp.net Mvc 5,我是ASP.NET MVC新手,只是想知道下一个场景的最佳实践是什么。我希望将查询结果传递给视图: public class HomeController : Controller { public ActionResult Index() // show last 3 posts from the database { DB db = new DB(); // DB is just a tiny wrapper to work with LocalDB sql database

我是ASP.NET MVC新手,只是想知道下一个场景的最佳实践是什么。我希望将查询结果传递给视图:

public class HomeController : Controller
{
  public ActionResult Index() // show last 3 posts from the database
  {
    DB db = new DB(); // DB is just a tiny wrapper to work with LocalDB sql database
    db.openConnection(ConfigurationManager.ConnectionStrings["PostDBContext"].ConnectionString);      
    db.select(@"select p.id, p.title, p.content, FORMAT(p.created_at, 'yyyy-MM-dd') as created_at, u.firstname,
                                u.lastname, c.name
                       from posts p
                               inner join users u on (u.id = p.created_by)
                               inner join categories c on (c.id = p.category_id)
                       where p.visibility = 'public'
                       order by p.id desc limit 3");

  while( db.read() > 0 ) // reads one row
  {
    ....
  }
  db.closeConnection();
  return View();
}
我读过几篇关于如何将数据从控制器传递到视图的文章。每篇文章都提到最好的推荐方法是将数据从模型传递到视图或创建ViewModels。因此,使用这种方法意味着我需要创建一个ViewModel和一个模型,如下所示:

public class FullPostViewModel
{
  public List<FullPost> Posts { get; set; }
}

public class FullPost
{
  public int id;
  public string title;
  public string content;
  public string created_at;
  public string author_firstname;
  public string author_lastname;
  public string category;
}
public class FullPost
{
  public Post p;
  public Category c;
  public User u;
}
还是最好制作三个模型:Post、Category、User,然后FullPost包含如下内容:

public class FullPostViewModel
{
  public List<FullPost> Posts { get; set; }
}

public class FullPost
{
  public int id;
  public string title;
  public string content;
  public string created_at;
  public string author_firstname;
  public string author_lastname;
  public string category;
}
public class FullPost
{
  public Post p;
  public Category c;
  public User u;
}
例如,如果您有更复杂的查询(3,4,…联接),这意味着为每个表创建新的类。当然,为每个表创建一个类是有意义的,因为这就是ORM的全部内容

我只想知道使用模型/视图模型是否始终是显示查询结果的最佳实践(我知道ViewBag用于简单和小数据)?在Laravel(PHP)中,当涉及连接的查询时,我通常不使用模型。这看起来很简单,但这并不意味着它可以

1)将应用程序分层。不要将SQL查询放在控制器中,而是放在服务层中

2) 您可以将业务对象返回到视图,但返回视图模型更好、更灵活。这样,您就不需要发送任何不需要的额外字段,并且可以将多个类混合到一个类中。此外,如果需要,还可以在控制器中处理格式设置

3) 如果你的观点充满逻辑,再想想,你可能做错了。尽量使用简单的视图,只需处理HTML和显示属性

根据一条评论,我在下面添加了额外信息:
有时,您需要设置十进制或DateTime属性的格式,或者将多个属性合并为一个。在控制器中比在视图中更好。假设您需要显示一个金额,包括货币和小数。您可以在视图或控制器中执行此操作。如果在视图中执行此操作,则视图中会有更多的逻辑。然后,如果同一页面有不同的视图(例如该页面的移动视图),则需要执行两次操作,或者为此创建部分视图。如果在控制器中执行此操作,则只需执行一次,即可轻松进行测试。

我建议您只需传递渲染视图所需的尽可能多或更少的数据。由于您可以创建许多视图模型,因此可以随意将属性放入其中

例如:

当您想显示帖子列表时:
返回视图(列表)
当您想详细显示帖子时:
返回视图(FullPost)

对于LightWeightFullPost,您可以只发送帖子名称和作者。这将使您发送的数据尽可能小,因为您不想在列表视图中显示每个细节

此外,仅当您确实需要时,才建议在ViewModel中传递复杂对象。
例如:在响应FullPost ViewModel时,您真的需要完整的Category对象吗?或者,一个CategoryId足够了吗?

您不一定需要
FullPostViewModel
模型。您只需将
List
传递给视图即可。您的第一个代码示例不会向视图发送任何内容。所以我甚至不确定这说明了什么。任何类型都可以用作视图模型,包括查询结果。如果要将数据转换为特定于该视图的内容,或包含特定于该视图的功能,则需要创建自定义视图模型。如果视图只是绑定到后端类型,您只需将后端查询的结果发送给它即可。另请参阅@StephenMuecke感谢您关于mvc中什么是viewmodel的帖子。@David我需要将查询结果存储到一些数据结构列表。。。SqlDataReader作为无缓冲的数据流工作。有必要关闭SqlDataReader,现在最好在视图中写入逻辑(SqlDataReader.close())。至于第一段代码,我只是想说明我正在尝试做什么(示例查询…),我同意关于简单视图的第3点。不完全理解控制器中的格式化是什么意思。有时需要格式化decimal或DateTime属性,或将多个属性合并为一个属性。在控制器中比在视图中更好。假设您需要显示一个金额,包括货币和小数。您可以在视图或控制器中执行此操作。如果您在视图中这样做,您将在视图中有更多的登录。然后,如果同一页面有不同的视图(例如该页面的移动视图),则需要执行两次操作,或者为此创建部分视图。如果在控制器中执行此操作,则只需执行一次即可轻松测试。