我在SO上读过类似的问题,但似乎无法弄清楚这个问题,这个问题特定于DBContext对象(我认为)。这里有一些虚拟代码来说明。
我的Index()操作中有以下代码:
public ActionResult Index()
{
AnimalDBContext db = new AnimalDBContext();
return View(db.Dogs);
}
我的模型有以下代码:
public class Dog
{
public int ID { get; set; }
public string name { get; set; }
public string breed { get; set; }
}
public class AnimalDBContext : DbContext
{
public DbSet<Dog> Dogs { get; set; }
}
在我看来,我有以下内容:
@model IEnumerable<AnimalProject.Models.Dog>
@foreach (var d in Model)
{
<h3>@d.name</h3>
<h2>@d.breed</h2>
}
一切都很好,视图将遍历我数据库中的每只狗。但是,我在同一视图中有另一组我想要的DBContext数据。我希望能够枚举数据库中该表的每个项目。
这就是我想要的,如果你抓住我的漂移:
@model IEnumerable<AnimalProject.Models.Dog>
@model IEnumerable<AnimalProject.Models.Cat>
@foreach (var d in Dog)
{
<h3>@d.name</h3>
<h2>@d.breed</h2>
}
@foreach (var c in Cat)
{
<h3>@c.name</h3>
<h2>@c.breed</h2>
}
我尝试将这些类组合在一起并使用局部视图,但显然您在局部视图中不能有不同的模型,因为我总是收到错误消息:
“模型项目传入 字典是类型 'System.Data.Entity.DbSet
1[AnimalProject.Models.Dog]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable
1 [AnimalProject.Models.Cat]'。“
那么,我如何在我的视图中使用多个模型,这两个模型都从数据库中的不同表中获取我想要的数据?
答案 0 :(得分:13)
如何创建自定义视图模型类:
public AnimalModel
{
public IEnumerable<Dog> Dogs { get; set; }
public IEnumerable<Cat> Cats { get; set; }
}
在Index中填写此模型并将其传递给期望AnimalModel
而不是枚举的视图。
修改强>
填写模型:
public ActionResult Index()
{
using (var db = new AnimalDBContext())
{
var model = new AnimalModel
{
Dogs = db.Dogs.ToList(),
Cats = db.Cats.ToList()
};
return View(model);
}
}
查看(我从未使用过剃刀,所以我希望这是正确的):
@model AnimalProject.Models.AnimalModel
@foreach (var d in Model.Dogs)
{
<h3>@d.name</h3>
<h2>@d.breed</h2>
}
@foreach (var c in Model.Cats)
{
<h3>@c.name</h3>
<h2>@c.breed</h2>
}
答案 1 :(得分:3)
模型只是一个对象,就像C#(或VB)
中的任何其他对象一样因此,您可以将任何想要的对象传递给视图,甚至是复杂的对象。如果您需要提供很多东西,那么创建一个视图模型(一个仅用于视图需求的模型),其中包含您要呈现的所有内容并将其传递给视图。然后,在视图中,您可以在视图的不同部分访问模型的各个属性,以显示它们。这种方法的一个例子是动物模型Ladislav Mrnka谈到的。你把狗和猫的枚举放在那里,然后将它传递给视图。你告诉视图你的模型现在是这个AnimalModel类型等等......
因此,由于模型只是一个对象,如果您懒得不想创建另一个自定义视图模型,那么您可以将整个dbcontext作为模型传递给视图,如下所示。
<强>控制器强>
public ActionResult Index()
{
return View(new AnimalDBContext()); // We pass a new instance of the dbcontext to the view
}
查看强>
@model AnimalProject.AnimalDBContext // we declare that our model is of type AnimalDBContext
@foreach (var d in Model.Dogs) // We reference the dbcontext's sets directly
{
<h3>@d.name</h3>
<h2>@d.breed</h2>
}
@foreach (var c in Model.Cats) // We reference the dbcontext's sets directly
{
<h3>@c.name</h3>
<h2>@c.breed</h2>
}
现在您已声明您的“Model”对象将是AnimalDBContext 因此,您可以直接从视图中访问所有AnimalDBContext的属性,设置等。它可能不是数据访问的最佳抽象,但看看你的控制器变得多么简单! :)你只需将整个世界扔进视图,让它决定挑选和呈现哪些部分......当然这是针对简单的场景。如果你想要更复杂的东西,你最终将不得不回归自定义视图模型。
答案 2 :(得分:0)
到目前为止,我发现这个问题的唯一解决方法是在ViewBag
中清除两个模型,然后为仅使用一个模型的部分渲染部分视图。当然,它只有在部分视图可分离时才有效 - 就像你的情况一样。与直接访问ViewBag
的内容相比,这允许强类型的部分视图。
解决方案类似于Ufuk的回答。首先将数据放在控制器的ViewBag
中:
ViewBag.Dogs = db.Dogs;
ViewBag.Cats = db.Cats;
然后从视图中渲染部分视图:
@Html.Partial("_ListDogs", ViewBag.Dogs)
@Html.Partial("_ListCats", ViewBag.Cats)
每个局部视图都沿着以下几行(例如_ListDogs.cshtml
):
@model IEnumerable<AnimalProject.Models.Dog>
@foreach (var d in Model)
{
<h3>@d.name</h3>
<h2>@d.breed</h2>
}