我是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();
}
我已经阅读了几篇关于如何将数据从控制器传递到视图的文章。每篇文章都提到最好的和推荐的方法是将数据从Model传递给View或创建ViewModels。所以使用这种方法意味着我需要创建一个ViewModel和一个Model,如下所示:
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;
}
然后在控制器中:
....
FullPostViewModel model = new FullPostViewModel();
while( db.read() > 0 ) // reads one row
{
model.Posts.Add( new FullPost(){id = Convert.ToInt32(db[0]), title = db[1], ....});
}
...
return View(model);
或者制作三个模型更好:帖子,类别,用户然后FullPost包含这样的内容:
public class FullPost
{
public Post p;
public Category c;
public User u;
}
如果您有更复杂的查询(3,4,...连接),这将意味着为每个表创建新类。当然,为每个表创建一个类是有意义的,因为这就是ORM的全部内容。
我只想知道使用Models / ViewModels是否始终是显示查询结果的最佳实践(我知道ViewBag的简单和小数据)?在Laravel(PHP)中,当涉及到涉及连接的查询时,我经常没有使用模型。它似乎更容易,并不意味着它的确定。
答案 0 :(得分:2)
我建议您只传递渲染视图所需的数据。由于您可以创建许多视图模型,因此您可以根据需要随意添加属性。
例如:
如果要显示帖子列表:return View(List<LightWeightFullPost>)
如果您想详细展示帖子:return View(FullPost)
对于LightWeightFullPost,您只需发送帖子名称和作者即可。这样可以使您发送的数据尽可能小,因为您不希望在列表视图中显示每个细节。
只有在您确实需要时,才建议在ViewModel中传递复杂对象。 例如:在响应FullPost ViewModel时,您真的需要完整的Category对象吗?或者是CategoryId足够吗?
答案 1 :(得分:1)
1)将您的应用程序分层。不要在控制器中放置SQL查询,在服务层中执行此操作。
2)您可以将业务对象返回给Views,但返回ViewModel会更好,更灵活。这样你就不需要发送任何你不需要的额外字段,你可以将多个类混合成一个。此外,如果需要,您可以在Controller中处理格式化。
3)如果您的View在所有地方都有逻辑,请再想一想,您可能做错了。尝试使用简单的视图,只需处理HTML并显示属性。
根据一条评论,我在下面添加了额外信息: 有时您需要格式化十进制或DateTime属性或将多个属性合并为一个属性。在Controller中比在View中更好。我们假设您需要显示金额,包括货币和小数。您可以在视图或控制器中执行此操作。如果您在视图中执行此操作,则视图中将包含更多逻辑。然后,如果您对同一页面有不同的视图(例如该页面的移动视图),则需要执行两次或为此创建局部视图。如果你在控制器中这样做,你可以做一次,你可以轻松测试它。