【问题标题】:Error when passing multiple tables from controller to view MVC4从控制器传递多个表以查看 MVC4 时出错
【发布时间】:2015-04-24 18:17:06
【问题描述】:

我尝试使用 ViewModel 将 2 个表从 Controller 传递给查看

我声明:

public class Temp
    {
        public Models.ORDER_HEADER_INFO ORDER_HEADER_INFO { get; set; }
        public Models.ORDER_ROUTING_DETAIL ORDER_ROUTING_DETAIL { get; set; }
    }

在控制器中我写:

public ActionResult DataLoading()
        {
            using (Models.AllDataEntities et = new Models.AllDataEntities())
            {
                var Odata = (from ord in et.ORDER_ROUTING_DETAIL join
                                oh in et.ORDER_HEADER_INFO on ord.ORDER_NO equals oh.ORDER_NO 
                                orderby  ord.TARGET_COMPLETION_FLAG,oh.PRODUCT_START_DATE
                         select new {Order_No = oh.ORDER_NO,ROUTING_NAME = ord.ROUTING_NAME,
                                     PJNO = oh.PJNO,DELIVERY_DESTINATION = oh.DELIVERY_DESTINATION,
                                      }).ToList();
                return View(Odata);
            }

        }

在视图中:

<table>
@for (int i = 0; i < Model.Count; i++ )
{
    <tr>
        <td>@Html.DisplayFor(m=>m[i].ORDER_HEADER_INFO.ORDER_NO)</td>
        <td>@Html.DisplayFor(m=>m[i].ORDER_HEADER_INFO.PJNO)</td>            
        <td>@Html.DisplayFor(m=>m[i].ORDER_ROUTING_DETAIL.ROUTING_NAME)</td> 
        <td>@Html.DisplayFor(m=>m[i].ORDER_HEADER_INFO.DELIVERY_DESTINATION)</td> 
    </tr>
}
</table>

当我运行代码时,出现这样的异常:

传入字典的模型项是类型 'System.Collections.Generic.List1[&lt;&gt;f__AnonymousType34[System.String,System.String,System.String,System.String]]', 但是这本词典需要一个类型的模型项 'System.Collections.Generic.List`1[TIS.Models.Temp]'。

当我调试时,数据已完全加载到 Odata,但我无法理解 Odata 的类型。

【问题讨论】:

  • 尝试改变这个 - select new Temp() {Order_No = oh.ORDER_NO,ROUTING_NAME = ord.ROUTING_NAME, PJNO = oh.PJNO,DELIVERY_DESTINATION = oh.DELIVERY_DESTINATION, }).ToList();
  • @ramiramilu - 无法工作,因为 Temp 没有 Order_No。
  • 当我在代码中添加 Temp 时,他们不明白什么是 Order_No、ROUTING_NAME、PJNO、DELIVERY_DESINATION
  • 您必须使用在 Temp 类中声明的属性名称。例如。新的 Temp(){ ORDER_HEADER_INFO.Order_No = oh.ORDER_NO}。
  • 是的,你是对的,但问题是你的模型需要 List,但你发送的是 List。因此,要么更改您的 Temp() 以保存所有值,要么定义新类型并将视图更改为相应的类型。

标签: asp.net-mvc asp.net-mvc-4


【解决方案1】:

你需要有这个选择语句。选择new Temp() { ... },而不是匿名类型。原因是您的视图期望 List&lt;temp&gt;,但您从控制器传递 list&lt;AnonymousType&gt;

var Odata = (from ord in et.ORDER_ROUTING_DETAIL join
             oh in et.ORDER_HEADER_INFO on ord.ORDER_NO equals oh.ORDER_NO 
             orderby  ord.TARGET_COMPLETION_FLAG,oh.PRODUCT_START_DATE
             select new Temp() {ORDER_HEADER_INFO = oh, ORDER_ROUTING_DETAIL = ord }).ToList();

如果您不想使用实体中的所有属性,则需要使用要使用的属性创建 DTO,并将它们映射到 linq 查询中。

【讨论】:

  • 无法工作,因为 Temp 没有 Order_No 或其他属性初始化。
  • 很高兴我的解决方案对您有所帮助。如果您认为它解决了您的问题,您可以将其标记为答案 :-)。
【解决方案2】:

您的服务器端代码应在创建列表时实例化 Temp 对象:

public ActionResult DataLoading()
{
    using (Models.AllDataEntities et = new Models.AllDataEntities())
    {
        var Odata = (from ord in et.ORDER_ROUTING_DETAIL join
                            oh in et.ORDER_HEADER_INFO on ord.ORDER_NO equals oh.ORDER_NO
                        orderby ord.TARGET_COMPLETION_FLAG, oh.PRODUCT_START_DATE
                        select new Temp()
                        {
                            ORDER_HEADER_INFO = new ORDER_HEADER_INFO()
                            {
                                ROUTING_NAME = ord.ROUTING_NAME
                            },
                            ORDER_ROUTING_DETAIL = new ORDER_ROUTING_DETAIL()
                            {
                                Order_No = oh.ORDER_NO
                            }
                        }).ToList();

        return View(Odata);
    }
}

你的视图可以像这样操作这个列表:

@model IEnumerable<MvcApplication16.Models.Temp>

<table>
@foreach (var item in Model)
{
    <tr>
        <td>@Html.DisplayFor(item.ORDER_HEADER_INFO.ORDER_NO)</td>
        <td>@Html.DisplayFor(item.ORDER_HEADER_INFO.PJNO)</td>            
        <td>@Html.DisplayFor(item.ORDER_ROUTING_DETAIL.ROUTING_NAME)</td> 
        <td>@Html.DisplayFor(item.ORDER_HEADER_INFO.DELIVERY_DESTINATION)</td> 
    </tr>
}
</table>

注意:在您原来的 Temp 对象定义中,您已直接映射实体,LINQ 将抛出您在评论中提到的错误。

实体或复杂类型“Model.ORDER_HEADER_INFO”不能 在 LINQ to Entities 查询中构造。

您不能(也不应该)投影到映射实体上。但是,您可以投影到匿名类型或 DTO。

我建议您创建您修改您的 Temp 定义并包含您想要发送到查看的属性。这将使它成为一个 ViewModel 对象,这是正确的方法。

public class Temp
{
   public string ORDER_NO { get; set; }
   public string ROUTING_NAME { get; set; }
}

【讨论】:

  • 我试过了,但出现错误:无法在 LINQ to Entities 查询中构造实体或复杂类型“Model.ORDER_HEADER_INFO”。
  • 哦,是的,这是因为您在模型中使用了实体。 LINQ 不允许。解决方案是,创建一个纯 DTO 对象。我会更新我的答案来解释它。
  • 有什么方法可以不用创建纯 DTO 对象吗?
猜你喜欢
  • 2020-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-06
  • 1970-01-01
  • 2017-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多