使用entity framework(.edmx模型)&Razor视图&&将数据库logging插入多个表创buildMVC3的下拉列表

在阅读了关于如何使用Razor Views在MVC 3中创buildDropDown列表的100篇文章之后,我找不到适合自己的案例。 所以在search答案的小时数和小时数之后,我决定发布这个问题,看看有没有人有答案,或者可以帮助我。 先谢谢你!!!

情况:我最终试图创build一个视图来添加一个员工到数据库。

下面是我正在使用的.EDMX模型的图像(将由create()使用的表格):

在这里输入图像描述

目标:

  1. 创build一个员工(我有CreateFshtml(强types)用部分视图为StaffNotifycheckbox){我在创build视图通知部分视图中使用单独的@model不知道,如果这是安全的? @model ShadowVenue.Models.Employee&@model ShadowVenue.Models.StaffNotify)

  2. 为StaffTypeId创build一个下拉框(它将从Table“StaffType”(它有一对多的关系)插入[StaffTypeId]值,但是会在下拉菜单中显示[Type]string值)

  3. 为GenderId创build一个下拉框(它将从表格​​“性别”(具有一对多关系)中插入[GenderId]值),但会在下拉列表中显示[Gender]string值)

  4. 将logging插入到数据库中(我在StaffId主键上有一个1对1关系的单独表中的员工通知)

我似乎遇到了这个控制器代码的麻烦。

我不确定是否应该在EDMX模型中创build存储过程,或者提出一些查询或方法的语法,不知道哪个是最好的方法。

这是我的第一个大型MVC3应用程序使用entity framework模型。

感谢您的时间。 我真的很感激这个网站的知识渊博的用户。

(如果您需要知道任何导航属性名称,以帮助解决scheme只是让我知道,我会提供给你)

不要直接将db模型传递给您的视图。 你很幸运能够使用MVC,所以使用视图模型进行封装。

像这样创build一个视图模型类:

public class EmployeeAddViewModel { public Employee employee { get; set; } public Dictionary<int, string> staffTypes { get; set; } // really? a 1-to-many for genders public Dictionary<int, string> genderTypes { get; set; } public EmployeeAddViewModel() { } public EmployeeAddViewModel(int id) { employee = someEntityContext.Employees .Where(e => e.ID == id).SingleOrDefault(); // instantiate your dictionaries foreach(var staffType in someEntityContext.StaffTypes) { staffTypes.Add(staffType.ID, staffType.Type); } // repeat similar loop for gender types } } 

控制器:

 [HttpGet] public ActionResult Add() { return View(new EmployeeAddViewModel()); } [HttpPost] public ActionResult Add(EmployeeAddViewModel vm) { if(ModelState.IsValid) { Employee.Add(vm.Employee); return View("Index"); // or wherever you go after successful add } return View(vm); } 

然后,最后在您的视图中(您可以使用Visual Studio首先对其进行脚手架),将inheritance的types更改为ShadowVenue.Models.EmployeeAddViewModel。 另外,在下拉列表中,使用:

 @Html.DropDownListFor(model => model.employee.staffTypeID, new SelectList(model.staffTypes, "ID", "Type")) 

和性别下拉类似

 @Html.DropDownListFor(model => model.employee.genderID, new SelectList(model.genderTypes, "ID", "Gender")) 

更新每个评论

对于性别,如果在上面build议的视图模型中没有genderTypes,也可以这样做(尽pipe如此,也许我会在视图模型中生成IEnumerable这个服务器端)。 所以,在下面的new SelectList...位置,您将使用您的IEnumerable。

 @Html.DropDownListFor(model => model.employee.genderID, new SelectList(new SelectList() { new { ID = 1, Gender = "Male" }, new { ID = 2, Gender = "Female" } }, "ID", "Gender")) 

最后,另一个选项是查找表。 基本上,您保持与查找types关联的键值对。 一个types的例子可能是性别,而另一个可能是国家等。我喜欢这样构造我的:

 ID | LookupType | LookupKey | LookupValue | LookupDescription | Active 1 | Gender | 1 | Male | male gender | 1 2 | State | 50 | Hawaii | 50th state | 1 3 | Gender | 2 | Female | female gender | 1 4 | State | 49 | Alaska | 49th state | 1 5 | OrderType | 1 | Web | online order | 1 

当一组数据不经常改变时,我喜欢使用这些表,但仍需要不时地列举。

希望这可以帮助!

呃,实际上我不得不说David对他的解决scheme是对的,但是有一些话题让我感到困扰:

  1. 你不应该把你的模型发送到视图=>这是正确的
  2. 如果你创build一个ViewModel ,并且在ViewModel包含Model作为成员,那么你就有效地将你的模型发送到View =>这是不好的
  3. 使用字典将选项发送到视图=>这不是很好的风格

那么你怎么能创造一个更好的耦合?

我将使用类似AutoMapper或ValueInjecter的工具来映射ViewModel和Model。 AutoMapper似乎有更好的语法和感觉,但目前的版本缺乏一个非常严重的话题:它不能执行从ViewModel到模型的映射(在某些情况下,如展平等,但这是脱离主题)所以目前我更喜欢使用ValueInjecter

所以你用ViewModel需要的字段创build一个ViewModel 。 您将查找所需的SelectList项添加。 而且你已经将它们添加为SelectLists。 因此,您可以从支持LINQ的源代码查询,selectID和文本字段并将其存储为select列表:您可以获得不必创build新的types(字典)作为查找,而只需从视图中移动new SelectList到控制器。

  // StaffTypes is an IEnumerable<StaffType> from dbContext // viewModel is the viewModel initialized to copy content of Model Employee // viewModel.StaffTypes is of type SelectList viewModel.StaffTypes = new SelectList( StaffTypes.OrderBy( item => item.Name ) "StaffTypeID", "Type", viewModel.StaffTypeID ); 

在你看来,你只需要打电话

 @Html.DropDownListFor( model => mode.StaffTypeID, model.StaffTypes ) 

回到你的方法在控制器的后期元素,你必须采取你的ViewModeltypes的参数。 然后你检查validation。 如果validation失败,则必须记住重新填充viewModel.StaffTypes SelectList,因为在inputpost函数时该项目将为空。 所以我倾向于把这些人口的东西分成一个函数。 如果有什么错误,你只需要return new View(viewModel) 。 MVC3发现的validation错误将自动显示在视图中。

如果您有自己的validation代码,则可以通过指定属于哪个字段来添加validation错误。 检查ModelState上的文档以获取相关信息。

如果viewModel有效,则必须执行下一步:

如果是创build新项目,则必须从viewModel填充模型(最适合的是ValueInjecter )。 然后,您可以将其添加到该types的EF集合并提交更改。

如果你有一个更新,你会得到当前的数据库项目第一个模型。 然后,您可以将viewModel的值复制回模型(再次使用ValueInjecter可以让您快速完成)。 之后,您可以SaveChanges并完成。

随意问,如果有什么不清楚。