我刚刚开始使用ASP.NET MVC,因为它处于测试阶段.在我的代码中,我正在运行一个简单的LINQ to SQL查询来获取结果列表并将其传递给我的视图.这种事:
var ords = from o in db.Orders where o.OrderDate == DateTime.Today select o; return View(ords);
但是,在我的视图中,我意识到我需要访问每个订单的客户名称.我开始使用,o.Customer.Name
但我很确定这是为每个订单执行单独的查询(因为LINQ的延迟加载).
减少查询数量的合理方法是同时选择客户名称.就像是:
var ords = from o in db.Orders from c in db.Customers where o.OrderDate == DateTime.Today and o.CustomerID == c.CustomerID select new { o.OrderID, /* ... */, c.CustomerName }; return View(ords);
除了现在我的"ords"变量是一个匿名类型的IEnumerable.
是否可以以这样的方式声明ASP.NET MVC视图:它接受IEnumerable作为其视图数据,其中T由从控制器传递的内容定义,或者我是否必须定义从我的查询填充的具体类型?
你能把它传递给视图吗?是的,但您的视图不会被强类型化.但帮手会工作.例如:
public ActionResult Foo() { return View(new {Something="Hey, it worked!"}); } //Using a normal ViewPage <%= Html.TextBox("Something") %>
那个文本框应该呈现"嘿,它有效!" 作为价值.
那么你可以定义一个视图,其中T是由从控制器传递给它的内容定义的吗?是的,但显然不是在编译时.
想一想.当您为视图声明模型类型时,您将获得视图的智能感知.这意味着必须在编译时确定类型.但问题是,我们可以在运行时从给定的东西中确定类型.当然,但没有强大的打字保留.
你怎么会得到一个你还不知道的智能感知器?控制器最终可以在运行时将任何类型传递给视图.我们甚至无法分析代码和猜测,因为动作过滤器可以改变传递给视图的对象.
我希望能够澄清答案而不会更多地模糊它.:)
您可以将匿名类型传递给视图,只需记住将模型转换为动态.
你可以这样做:
return View(new { MyItem = "Hello", SomethingElse = 42, Third = new MyClass(42, "Yes") })
在视图的顶部,您可以这样做(在这里使用剃刀)
@{ string myItem = (dynamic)Model.MyItem; int somethingElse = (dynamic)Model.SomethingElse; MyClass third = (dynamic)Model.Third; }
或者您可以像这样从ViewData中转换它们:
@{ var myItem = ViewData.Eval("MyItem") as string var somethingElse = ViewData.Eval("SomethingElse") as int? var third = ViewData.Eval("Third") as MyClass }
在.NET 4.0上,匿名类型可以很容易地转换为ExpandoObjects,因此所有问题都可以通过转换本身的开销来解决.看看这里