【问题标题】:Passing entity framework query to view error传递实体框架查询以查看错误
【发布时间】:2014-08-08 15:09:27
【问题描述】:

我刚刚使用实体框架代码优先方法创建了一个数据库。

这是我的模态类

public class MobileProduct
{
    [Key]
    public int p_id { get; set; }
    public string  p_name { get; set; }
    public string  p_description { get; set; }

    public string p_price { get; set; }
}

这是我的 DbContext 派生类

public class Entities : DbContext
{
   public DbSet<MobileProduct> Mobiles { get; set; }
}

我刚刚创建了一个查询来将此数据传递给操作方法的视图

Entities db = new Entities();
public ActionResult Mobiles()
{
    var q = from n in db.Mobiles
            select n;
    return View(q);
}

这是我的观点

@model HomeShopping.Models.MobileProduct

@{
    ViewBag.Title = "Mobiles";
}

<h2>Mobiles</h2>

访问视图时出现错误

传入字典的模型项的类型为“System.Data.Entity.Infrastructure.DbQuery`1[HomeShopping.Models.MobileProduct]”,但此字典需要“HomeShopping.Models.MobileProduct”类型的模型项.

说明:在执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.InvalidOperationException:传入字典的模型项的类型为“System.Data.Entity.Infrastructure.DbQuery`1[HomeShopping.Models.MobileProduct]”,但此字典需要类型的模型项'HomeShopping.Models.MobileProduct'。

【问题讨论】:

  • 问题是什么?

标签: c# asp.net-mvc entity-framework asp.net-mvc-4 localdb


【解决方案1】:

我想您想将 MobileProduct 列表发送到视图?如果是这样的话;将您的模型更改为

@model IEnumerable<HomeShopping.Models.MobileProduct>

@{
    ViewBag.Title = "Mobiles";
}

<h2>Mobiles</h2>

目前,您的模型只需要一个 MobileProduct 类型的实例,而您的 Mobiles 操作正在创建一个 MobileProduct 列表。您还需要通过对其执行 ToList() 来评估操作中的查询。

public ActionResult Mobiles()
        {
            var q = from n in db.Mobiles
                    select n;
            return View(q.ToList());
        }

【讨论】:

  • 不必先将查询评估为列表。
  • System.Data.Entity.Infrastructure.DbQuery 实现了IEnumerable,所以不需要ToList,但无论如何我要+1,因为第一部分是正确的。
  • 您不需要在这个特定示例中进行评估,但您不应该在将所有内容发送回视图之前处理您的上下文吗? (好久没用EF了……)
  • @DavidG 您只不需要评估 DbQuery,因为上下文没有在操作中处理。向视图发送查询只是自找麻烦,因为它取决于先前未处理的上下文。这不是一个可靠的模式。但是从技术上讲,您是正确的; ToList() 在这里不是严格要求的。
  • @daveL 绝对可以,但是正如您在回答中所说的那样,最好解释一下您为什么这样做。前半部分很好地回答了问题,后半部分是很好的实践。
【解决方案2】:

您没有意识到您的查询,因此您将查询本身而不是查询结果发送到视图。

var q = (from n in db.Mobiles
         select n).ToList();
return View(q);

正如 daveL 所发布的,您还需要更改视图中模型的定义。

@model IEnumerable<HomeShopping.Models.MobileProduct>

【讨论】:

  • 您的第二点是正确的,但无论哪种方式都不需要强制转换为列表。主要问题是 OP 发送了一个可枚举的视图,该视图期望单个对象。 OP 仅通过强制转换为列表会得到相同的错误,并且它也可以使用可枚举模型定义直接将可查询对象发送到视图。
  • 向视图发送查询是,IMO,一个非常糟糕的主意,我不希望看到这种模式重复。实现视图,然后发送数据,以防止潜在的昂贵操作被处理查询的视图而不是 DTO 集合隐藏。
  • 我个人同意,但这并不能改变它不是必需的事实。可以说你应该这样做,但传达它必须这样做是不正确的。
【解决方案3】:

尚未测试,但尝试将您的模型定义为:

@model IQuerable<HomeShopping.Models.MobileProduct>

如果这不起作用,那么也许:

@model IEnunerable<HomeShopping.Models.MobileProduct>

...您的对象返回为:

View(q.ToList());

【讨论】:

    【解决方案4】:

    您将查询保存到 q,而不是查询的评估。如果您期望多个结果,则需要 ToList()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-22
      • 1970-01-01
      • 1970-01-01
      • 2017-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多