对对象的 MVC4 linq 查询未显示为正确的对象

问题描述 投票:0回答:3

错误:传递到字典中的模型项的类型为“System.Data.Entity.Infrastruct.DbQuery(snip)...寻找类型“Advocate”

控制器方法如下所示:

[HttpGet]
public ActionResult AdvocateEdit(int id)
{
    var advocate = from a in db.Query<Advocate>().Include(a => a.AdvocateId)
                   where (a.AdvocateId == id)
                   select a;

    return View(advocate);
}

该视图确实被输入到 Advocate @model,单步执行后,我很确定问题出在这个查询上。返回时它需要是 Advocate 类型。

db.Query is an IQueryable<T> method in my DbContext that returns Set<T>().

如果需要更多信息,请告诉我。 谢谢大家

已添加 ----

DbContext.cs

public interface IAcmeDb : IDisposable
{
    IQueryable<T> Query<T>() where T : class;
}

public class AcmeDb : DbContext, IAcmeDb
{
    public AcmeDb() : base("name=AcmeDB") {}
    public DbSet<Advocate> Advocates { get; set; }

    IQueryable<T> IAcmeDb.Query<T>()
    {
         return Set<T>();
    }
}
c# asp.net-mvc linq iqueryable
3个回答
4
投票

我认为您想要将 Advocate 元素传递给视图,而不是查询本身。试试这个:

return View(advocate.First());

代码中的 Advocate 对象是 IQueryable 类型,如果您的视图需要 Advocate 对象,只需使用 First() 或 FirstOrDefault() 获取查询的第一个元素即可。


3
投票

如果您的视图需要单个

Advocate
并且给定 id 始终只有一个实体,那么您需要:

[HttpGet]
public ActionResult AdvocateEdit(int id)
{
   try
   {
       Advocate advocate = db.Query<Advocate>().Single(a => a.AdvocateId == id);
       return View(advocate);
   }
   catch(InvalidOperationException ex)
   {
      //handle the case where no entity matches the supplied id (return status code 404?), or
      //there are no Advocates at all (redirect to a create page?), or
      //more than one entity matches (return status code 500)
   }
}

2
投票

至少有一个值得注意的问题。 LINQ倾向于使用延迟执行。我在您的代码中没有看到您强制执行查询。除非在

View(advocate)
中的某个地方枚举了查询生成的
IEnumerable<T>
,否则您将不会处理
Advocate
类型的对象。

我建议在查询末尾添加

ToList()
ToArray()
调用,这将确保它实际执行。如果这不起作用,我会分解查询并确保
db.Query<Advocate>()
返回您期望的结果。

   List<Advocate> = db.Query<Advocate>()
                      .Include(a => a.AdvocateId)
                      .Where(a.AdvocateId == id)
                      .Select(a => a).ToList();

我已将您的查询转换为方法语法,因为这是我所熟悉的。上面的例子可能会解决你的问题。我认为要保留查询语法,您应该将整个左侧放在父项中,然后添加

ToList()
调用,但我不确定正确的语法是什么。

编辑:根据其他评论,问题不是延迟执行,而是尝试将集合传递给寻找单个实例的方法。使用上面相同的代码,您只需将

ToList()
更改为
FirstOrDefault()
,您的代码就可以工作;

List<Advocate> = db.Query<Advocate>()
                   .Include(a => a.AdvocateId)
                   .Where(a.AdvocateId == id)
                   .Select(a => a)
                   .FirstOrDefault();

注意:引用类型的默认值是

null
如果您没有对无效性进行适当的检查,这当然可能会给您带来问题。

© www.soinside.com 2019 - 2024. All rights reserved.