我正在将现有程序转换为MVC5,我需要从数据库中连接多个表。我做了一个虚拟项目项目进行实验,所以我没有无可挽回地破坏任何东西,我让它成功地拉动并显示数据库的所有单独的表。但是,当我尝试加入它们时,我得到“对象引用未设置为对象的实例。”
注意:产品和任务是DB中的现有模型和表。它已经部署,我们无法改变它们。
相关控制器代码:
public ActionResult Index()
{
_db.Configuration.ProxyCreationEnabled = false;
var JoinTest = (
from a in _db.Task.AsEnumerable()
join b in _db.Product on a.ProductId equals b.ProductId
select new
{
TaskId = a.TaskId,
TaskDesc = a.TaskDescription,
ProdDesc = b.ProductDescription
});
ViewData["CompositeData"] = JoinTest;
ViewData["ProductData"] = _db.Product.ToList();
}
查看代码:
@foreach (var item in ViewData["CompositeData"] as List<TomFoolery.Models.ViewModel>)
{
//Printing relevant items from DB
}
而且,要彻底,ViewModel的定义:
namespace TomFoolery.Models
{
public class ViewModel
{
public Product Product { get; set;}
public Task Task { get; set; }
}
}
那么,我哪里错了?
答案 0 :(得分:0)
ViewData["CompositeData"] as List<TomFoolery.Models.ViewModel>
将返回null,因为您设置为ViewData["CompositeData"]
的项目是匿名类型的列表。
您应该创建一个视图模型并使用它。
public class MyViewModel
{
public int TaskId {set;get;}
public string TaskDesc {set;get;}
public string ProductDesc {set;get;}
}
并在投影部分使用它。
ViewData["CompositeData"] = (
from a in _db.Task.AsEnumerable()
join b in _db.Product on a.ProductId equals b.ProductId
select new MyViewModel
{
TaskId = a.TaskId,
TaskDesc = a.TaskDescription,
ProdDesc = b.ProductDescription
}).ToList();
并且在视图中,您需要转换为此视图模型集合。
@foreach (var item in ViewData["CompositeData"] as List<TomFoolery.Models.MyViewModel>)
{
<p>@item.TaskId</p>
}
您也可以考虑取消使用ViewData,并寻求完整的强类型视图模型方法。为您的视图创建视图模型
public class MyPageViewModel
{
public List<MyViewModel> Tasks {set;get;}
public List<Product> Products {set;get;}
}
并且在您的GET操作中,不是设置为ViewData,而是创建此视图模型的对象并设置为它的相应属性
var vm = new MyPageViewModel();
vm.Products = _db.Product.ToList();
vm.Tasks = (
from a in _db.Task.AsEnumerable()
join b in _db.Product on a.ProductId equals b.ProductId
select new MyViewModel
{
TaskId = a.TaskId,
TaskDesc = a.TaskDescription,
ProdDesc = b.ProductDescription
}).ToList();
return View(vm);
并在您的视图中强烈输入我们的新视图模型
@model MyPageViewModel
@foreach(var item in Model.Tasks)
{
<p>@item.TaskId</p
<p>@item.TaskDesc</p>
<p>@item.ProdDesc</p>
}
答案 1 :(得分:0)
_references.js
ViewData["CompositeData"] = JoinTest;
是JoinTest
,因此您无法将其投放到IEnumerable<anonymous_type>
。
List<TomFoolery.Models.ViewModel>