控制器 returns 值与视图不匹配?

Controller returns value that not match with view?

我有两个class,第一个是基础class,第二个是继承自第一个。

public class hgm
{ 
}

public class Laboratory : hgm
{
}

我使用 EF Code First 生成数据库。另外,我使用了默认的 Scaffold 来生成控制器和视图。

我可以使用编辑、创建、详细信息页面,但对于索引(实例列表),出现错误:

The model item passed into the dictionary is of type 'System.Collections.Generic.List'1[armnab.Models.hgm]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable'1[armnab.Models.Laboratory]'

这是我的控制器:

public class LaboratoriesController : Controller
{
    private hgmContext db = new hgmContext();

    // GET: Laboratories
    public ActionResult Index()
    {
        return View(db.hgms.ToList());
    }
}

和视图:

@model IEnumerable<armnab.Models.Laboratory>

<h2>Index</h2>

为什么会出现这个错误?

如果 Lab 继承自 hgm,您应该在控制器中传递实验室列表或更改此列表 IEnumerable<armnab.Models.Laboratory>到这个 IEnumerable<armnab.Models.hgm>.

除非您明确地对其进行类型转换,否则虽然实验室是 hgm,但 hgm 不一定是实验室,因此您不能直接分配它。

您的视图需要 Laboratory 的 IEnumerable。您正在 return

List<hgm> 

而不是

List<Laboratory>

你可能真的想要 return db.Laboratories.ToList() 或者如果 hgm 对象有实验室作为 属性 你需要 select hgm 符合标准并且 return 来自这个的实验室,例如

var result = db.hgm.Where(x => x.someProperty == someValue).ToList();
if(result.Count > 0)
{
   return hgm.Laboratories;
}

泛型中没有继承 类 (read this for additional details)
如果你从数据库中 select 得到的所有对象都是 laboratory 对象,那么你可以使用 Cast<Laboratory> linq 方法。如果您希望所有 hgm 对象都被视为 laboratory 对象,那么您需要为每个从数据库获取的 hgm 创建新的 laboratory 对象并映射所有属性(您可以为此使用一些库,例如 AutoMapper or ValueInjecter

public ActionResult Index()
    {
        return View(db.hgms.Select(x => GetLaboratoryFromHgm(x));
    }

private Laboratory GetLaboratoryFromHgm(Hgm obj) 
{
      var lab = new Laboratory();
      //map all the properties here
}

由于您的 DbContext 是 returning hgm 个实例,并且您希望填充为 Laboratories 实现的视图,因此您需要将值转换为 Laboratory 类型。由于您不能保证 DbContext 只会 return Laboratory 实例(给定您的问题范围),因此 Cast 运算符可能会抛出异常。

鉴于问题中的信息,最佳选择是 OfType,它不会 return 类型不正确的值。

public ActionResult Index()
{
    return View(db.hgms.OfType<Laboratory>());
}