我想了解(并且最后欣赏,因为现在只是痛苦...)MVC中的更多ViewModel和强类型视图。
我的 ViewModel
public class Combined
{
public IEnumerable<Domain> Domains { get; set; }
public IEnumerable<RegInfo> RegInfos { get; set; }
public Combined(IEnumerable<Domain> domains, IEnumerable<RegInfo> reginfos)
{
this.Domains = domains;
this.RegInfos = reginfos;
}
在控制器中,我将数据从存储库传递到Combined类型的对象。
public ActionResult RegDetails(int id = 0)
{
var domain = from x in unitofwork.DomainRepository.Get(n => n.ID == id)
select x;
var reginfo = from y in unitofwork.ReginfoRepository.Get(n => n.ID == id)
select y;
var regdetails = new Combined(domain, reginfo);
return View(regdetails);
}
在一个视图中(使用Razor)我有@model project.namespace.Combined所以我传递了一个包含两个列表的对象。
1 /为什么我不能像这样访问每个列表项@ Model.Domain.Name(noobish question但请帮我理解它背后的逻辑)?我可以通过使用连接来查看“级别”,但它完全违反MVC模式。我认为只有连接这两个表的地方是在Controller中,但它会创建一个全新的对象,所以我需要为它创建一个模型吗?
2 /获取IEnumerable对象的最佳方法是什么,该对象将保存来自2个或更多表的数据,这些表可用于填充View(join,automapper)?
3 /是否有一种方法可以让我创建一个模型,我可以使用它从一个表格POST到多个表格?
提前致谢。
答案 0 :(得分:5)
在控制器动作中获取实体的逻辑很好;这是控制器的工作。但是,您不需要在视图模型上使用自定义构造函数:只需使用对象初始化。
var regdetails = new Combined { Domains = domain, RegInfos = reginfo }
现在,就您的视图模型而言,Domains
和RegInfos
为IEnumerable
,但您只为每个模型提取一个对象。如果您打算使用列表类型,那么您应该修改LINQ以选择多个项目,但如果您的意图实际上只是每个项目只有一个,那么您不应在视图中使用IEnumerable
s模型。
public class Combined
{
public Domain Domain { get; set; }
public RegInfo RegInfo { get; set; }
}
如果您这样做,那么您将能够仅使用Name
访问Domain
实例上的@Model.Domain.Name
媒体资源。但是,如果你保留它们的列表类型,那么你必须在视图中循环它们(即使列表中只有一个项目):
@foreach (var domain in Model.Domains)
{
// Do something with domain.Name
}
答案 1 :(得分:2)
您在视图中确实获得了一个Model属性,您可以像使用c#一样使用Domains和RegInfos属性。例如:
@{
var firstDomain = Model.Domains.FirstOrDefault();
// do some process with this variable
}
或者:
@foreach(var regInfo in Model.RegInfos)
{
// do some other process
}
如果显示的数据来自各种数据源,则最好制作特定的视图模型。您需要避免在视图中进行计算或应用业务规则,数据应在此之前预先格式化。另一个好处是只将所需的数据传递给您的视图:您不希望仅为2个显示的属性从数据库中获取大型对象(或集合)。
提交表单时也可以使用该视图模型。如果您的帖子操作具有视图模型类型的参数,并且您在视图中正确生成输入(通过使用某些HtmlHelper,如Html.Editor(For)等),则可以取回它。
无论如何,关于强类型视图有很多话要说,并且可以在网络上找到许多资源/教程。