Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework 使用实体框架(.edmx模型)为MVC3创建一个下拉列表&;剃须刀视图及&;将数据库记录插入多个表_Entity Framework_Asp.net Mvc 3_Razor_Edmx_Html.dropdownlistfor - Fatal编程技术网

Entity framework 使用实体框架(.edmx模型)为MVC3创建一个下拉列表&;剃须刀视图及&;将数据库记录插入多个表

Entity framework 使用实体框架(.edmx模型)为MVC3创建一个下拉列表&;剃须刀视图及&;将数据库记录插入多个表,entity-framework,asp.net-mvc-3,razor,edmx,html.dropdownlistfor,Entity Framework,Asp.net Mvc 3,Razor,Edmx,Html.dropdownlistfor,在阅读了100篇关于如何在MVC 3中使用Razor视图创建下拉列表的文章后,我找不到一篇适合我的文章 情况: 我最终尝试创建一个视图,将员工添加到数据库中 下面是我正在使用的.EDMX模型的图像(create()将使用的表): 目标: 创建员工(我使用StaffNotify复选框的部分视图创建了Create.cshtml(强类型){我在通知部分视图中使用的@model与创建视图中的@model不确定是否安全???@model ShadowVenue.Models.Employee&@mode

在阅读了100篇关于如何在MVC 3中使用Razor视图创建下拉列表的文章后,我找不到一篇适合我的文章

情况: 我最终尝试创建一个视图,将员工添加到数据库中

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

目标:

  • 创建员工(我使用StaffNotify复选框的部分视图创建了Create.cshtml(强类型){我在通知部分视图中使用的@model与创建视图中的@model不确定是否安全???@model ShadowVenue.Models.Employee&@model ShadowVenue.Models.StaffNotify)

  • 为StaffTypeId创建一个下拉框(该框将插入表“StaffType”(具有1对多关系)中的[StaffTypeId]值,但将在下拉框中显示[Type]字符串值)

  • 为GenderId创建一个下拉框(该框将插入表“Genders”(具有1对多关系)中的[GenderId]值,但将在下拉框中显示[GenderId]字符串值)

  • 将记录插入数据库(我将StaffId主键上的Staff通知放在一个单独的表中,表中的关系为1:1)

  • 我似乎在控制器代码方面遇到了问题

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

    这是我第一个使用实体框架模型的大型MVC3应用程序


    (如果您需要知道任何导航属性名称以帮助解决方案,请告诉我,我会提供给您)

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

    创建一个视图模型类,如下所示:

    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
        }
    }
    
    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
    
    最后,在您的视图中(您可以使用Visual Studio首先构建它),将继承的类型更改为ShadowVincement.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"))
    
    根据评论更新

    对于性别,如果您可以在上面建议的视图模型中不使用性别类型,您也可以这样做(不过,仔细想想,也许我会在视图模型中将此服务器端生成为IEnumerable)。因此,您可以使用IEnumerable来代替下面的
    new SelectList…

    @Html.DropDownListFor(model => model.employee.genderID,
        new SelectList(new SelectList()
        {
            new { ID = 1, Gender = "Male" },
            new { ID = 2, Gender = "Female" }
        }, "ID", "Gender"))
    
    最后,另一个选项是查找表。基本上,您将键值对与查找类型关联。一个类型的示例可能是性别,而另一个可能是状态等。我喜欢这样构造我的类型:

    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
        }
    }
    
    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
    
    当一组数据不经常更改,但仍需要不时枚举时,我喜欢使用这些表


    希望这能有所帮助!

    事实上,我不得不说大卫的解决方案是正确的,但有一些话题让我感到不安:

  • 永远不要将模型发送到视图=>这是正确的
  • 如果您创建了一个
    ViewModel
    ,并将模型作为成员包含在
    ViewModel
    中,那么您将模型有效地发送到视图=>这是错误的
  • 使用字典将选项发送到视图=>这不是好样式
  • 那么,如何创建更好的耦合呢

    我会使用像
    AutoMapper
    这样的工具,或者在
    ViewModel
    和Model之间进行映射。
    AutoMapper
    似乎有更好的语法和感觉,但当前版本缺少 非常严重的主题:它无法执行从
    ViewModel
    到模型的映射(在某些情况下,如展平等,但这与主题无关) 所以目前我更喜欢使用
    valueinjector

    因此,您可以使用视图中所需的字段创建一个
    ViewModel
    。 您可以添加所需的SelectList项作为查找。 您已经将它们添加为selectlist。因此,您可以从启用LINQ的sourc进行查询,选择ID和文本字段,并将其存储为selectlist: 您不必创建新类型(字典)作为查找,只需将
    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
        );
    
    回到控制器中方法的post元素,您必须获取
    ViewModel
    类型的参数。然后检查验证。 如果验证失败,您必须记住重新填充
    viewModel.StaffTypes
    SelectList,因为该项在进入post函数时将为空。 所以我倾向于把这些总体的东西分解成一个函数。 如果有任何错误,只需回调
    返回新视图(viewModel)
    。 MVC3发现的验证错误将自动显示在视图中

    如果您有自己的验证代码,则可以通过指定验证错误所属的字段来添加验证错误。请查看
    ModelState
    上的文档以获取有关该错误的信息

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

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

    如果有更新,则首先将当前db项复制到模型中。然后可以将值从
    viewModel
    复制回模型中(再次使用
    valueinjector
    可以非常快速地完成此操作)。 之后,您可以
    保存更改
    并完成更改


    如果有任何不清楚的地方,请随时询问。

    检查问题。请参阅我的教程,使用DropDownList框和jQuery()以及我的博客级联DropDownList,它位于ASP.Net MVC()+1 for AutoMapper中。它使