1

我是 MVC 的新手,所以如果我的问题听起来很愚蠢或太简单,请原谅。我正在使用实体数据模型进行数据库访问。所以在我的模型文件夹中,我添加了一个 EDMX 文件,我可以从我的控制器和强类型视图中访问模型类。当我在控制器中访问多个表时会出现问题,例如

如果我的数据库中有以下表格:

 Departments(DepartmentID, DepartmentName, DepartmentPhone)
 Insurances(InsuranceID, InsuranceName, InsuranceAddress)
 Employees(EmployeeID, EmpFName, EmpLName, DepartmentID, InsuranceID)

我想显示一个员工列表以及他们的部门和保险信息。

在我的控制器的操作方法中,我使用 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);
        }

我的模型文件夹中没有这种匿名类型的类,因此我无法创建强类型视图。那么将此列表传递给视图的最佳方法是什么?如果集合太大,使用 viewbag 将是一种过度杀伤力。为这个匿名类创建一个新模型听起来不正确,因为如果我在控制器操作方法中更改我的选择,它需要一直更新。

欢迎所有建议。我尝试查看有关 SO 的其他问题,但找不到任何相关内容。

谢谢。

4

3 回答 3

2

我的模型文件夹中没有这种匿名类型的类,所以我无法创建强类型视图

右键单击您的项目,添加新类 ... 现在您的模型文件夹中有一个类型。这是 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>
...
于 2012-07-12T06:55:24.627 回答
0

I'm afraid that predefined strongly-typed ViewModels are the way to go. It is a pain to have to update seemingly duplicate code in multiple places but in my experience it's only a problem for smaller projects. As the project grows you begin to see differences between database model objects (entities) and the viewmodels passed to your views, such as Validation and processing attributes and view-specific data, and when you get to that point you begin to prefer having separate Entity and ViewModel definitions.

However, back on-topic: an alternative solution to your problem is to use reflection to convert an anonymous type into a Dictionary<String,Object> object. Note that ASP.NET MVC does this for converting new { foo = "bar" }-syntax expressions into dictionaries for Route Values and HTML attributes already. Performance is acceptable, but don't try to do it for 10,000 objects for a single HTTP request otherwise you might get bogged down.

Here's what the code for that would look like:

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 );
}

Of course this means that your Views won't benefit from compile-time type-checking and you'll have to maintain a documented list of dictionary keys (assuming you aren't iterating over keys in your view).

I'll note that I am surprised Microsoft didn't make anonymous types automatically implement IDictionary because it seems natural.

于 2012-07-11T23:57:20.257 回答
0

动态类型是你的朋友。

您可以将视图声明为松散类型,并具有动态模型

@model dynamic

您将像在强类型视图中一样访问模型属性

<h1>Model.DepartmentId</h1> - <h2>Model.DepartmentName</h2>
<span>Model.EmployeeId</span>

问题认为,动态包含内部属性,如果您使用的是 MVC2,则需要一个小技巧才能使其工作。但似乎对于 MVC3 及更高版本,它不再需要。

于 2012-07-12T06:50:57.750 回答