我是MVC的新手,所以如果我的问题听起来很愚蠢或太简单,请原谅。我正在使用实体数据模型进行数据库访问。所以在我的Models文件夹中,我添加了一个EDMX文件,我可以从我的控制器和强类型视图访问模型类。当我在控制器中访问多个表时会出现问题,例如
如果我的数据库中有以下表格:
Departments(DepartmentID, DepartmentName, DepartmentPhone)
Insurances(InsuranceID, InsuranceName, InsuranceAddress)
Employees(EmployeeID, EmpFName, EmpLName, DepartmentID, InsuranceID)
我想显示员工名单及其部门和保险信息。
在我的Controller的操作方法中,我使用EDM访问数据库,并以匿名类型获取信息:
using (var context = new MyEntities())
{
var model = (from d in context.Departments
join e in context.Employees on d.DepartmentID equals e.DepartmentID
join I in context.Insurances on I.InsuranceID equals e.InsuranceID
select new
{
DepartmentID = d.DepartmentID,
EmployeeID= e.EmployeeID,
EmpFName= e.EmpFName,
EmpLName= e.EmpLName,
DepartmentName= d.DepartmentName,
InsuranceName= I.InsuranceName
}).ToList();
return View(model);
}
我的Model文件夹中没有这个匿名类的类,所以我无法创建强类型视图。那么将此列表传递给View的最佳方法是什么?如果集合太大,使用viewbag将是一种过度杀伤。为这个匿名类创建一个新模型听起来不对,因为如果我在控制器操作方法中更改我的选择,它需要一直更新。
欢迎所有建议。我尝试在SO上查看其他问题,但找不到任何相关内容。
感谢。
答案 0 :(得分:2)
我的Model文件夹中没有这个匿名类的类,所以我 无法创建强类型视图
右键单击您的项目,添加新类...现在您在Model文件夹中有一个类型。这是ASP.NET MVC =>的方法。查看模型。
然后显然你将这种类型传递给你的观点:
select new MyViewModel
{
DepartmentID = d.DepartmentID,
EmployeeID = e.EmployeeID,
EmpFName = e.EmpFName,
EmpLName = e.EmpLName,
DepartmentName = d.DepartmentName,
InsuranceName = I.InsuranceName
}).ToList();
当然,现在您的视图会强烈输入此视图模型:
@model IEnumerable<MyViewModel>
...
答案 1 :(得分:0)
我担心预定义的强类型ViewModel是可行的方法。在多个地方更新看似重复的代码是一件痛苦的事情,但根据我的经验,这对于较小的项目来说只是一个问题。随着项目的增长,您开始看到数据库模型对象(实体)与传递给视图的视图模型之间的差异,例如验证和处理属性以及特定于视图的数据,当您到达那一点时,您开始更喜欢使用单独的实体和ViewModel定义。
但是,回到主题:您的问题的替代解决方案是使用反射将匿名类型转换为Dictionary<String,Object>
对象。请注意,ASP.NET MVC执行此操作以将new { foo = "bar" }
- 语法表达式转换为路径值和HTML属性的字典。性能是可以接受的,但是不要为单个HTTP请求尝试为10,000个对象执行此操作,否则您可能会陷入困境。
这里的代码是什么样的:
Object anonymousType = new { whatever = "foo" };
Dictionary<String,Object> dict = new Dictionary<String,Object>();
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(anonymousType )) {
Object value = descriptor.GetValue(anonymousType );
dict.Add( descriptor.Name, value );
}
当然这意味着您的视图不会受益于编译时类型检查,并且您必须维护一个记录的字典键列表(假设您不是在重复键入你的观点)。
我注意到我很惊讶微软并没有让匿名类型自动实现IDictionary,因为它似乎很自然。
答案 2 :(得分:0)