asp.net-mvc 使用 Entity Framework 6 和 ViewModel 从数据库表中填充 ASP.NET MVC 中的 DropDownList

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42549622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:36:38  来源:igfitidea点击:

Populate DropDownList in ASP.NET MVC from database table using Entity Framework 6 and ViewModel

asp.net-mvcentity-frameworkrazorviewmodeldropdownlistfor

提问by TropicalViking

I have been scratching my head for a whole night on an issue I can do quickly using ajax/jquery and stored procedures. I want to

我整晚都在摸索一个问题,我可以使用 ajax/jquery 和存储过程快速解决这个问题。我想要

1) Populate a drop down list from values obtained from a database table using Entity Framework and view model. I DO NOT WANT TO USE VIEWBAG OR VIEWDATA. Any help appreciated.

1) 使用实体框架和视图模型从从数据库表中获得的值填充下拉列表。我不想使用 VIEWBAG 或 VIEWDATA。任何帮助表示赞赏。

2) How can I generate a Create View using the View Model with the all the default fields ? The scaffholding works on a model but not on a view model ?

2) 如何使用带有所有默认字段的视图模型生成创建视图?脚手架适用于模型但不适用于视图模型?

MY MODELS

我的模特

public class Employee
{
    public int EmployeeID { get; set; }
    public string Name { get; set; }
    public string Gender { get; set; }
    public string City { get; set; }
    public string Level { get; set; }
    public int DepartmentId { get; set; }
}

public class Grade
{
    public int ID { get; set; }
    public string Level { get; set; }
}

View Model

查看模型

public class GradeSelectListViewModel
{

    public Employee Employee { get; set; }
    public IEnumerable<SelectListItem> Grades { get; set; }
    public GradeSelectListViewModel(Employee employee, IEnumerable grades)
    {
        Employee = employee;
        Grades = new SelectList(grades, "Grade", "Name", employee.Level);
    }
}

MY CONTEXT CLASS

我的上下文类

public class EmployeeContext : DbContext
{
    public DbSet<Employee> Employees { get; set; }
    public DbSet<Department> Departments { get; set; }
    public DbSet<Grade> Grades { get; set; }
}

MY CONTROLLER

我的控制器

public ActionResult Edit (int? id)
{
    using (var db = new EmployeeContext())
    {
        var model = new GradeSelectListViewModel(db.Employees.Find(id), db.Grades);
        //model.Employee = db.Employees.Single(x => x.EmployeeID == id);
        model.Grades = db.Grades.ToList().Select(x => new SelectListItem
        {
            Value = x.ID.ToString(),
            Text = x.Level
        });
        return View(model);
    }
}

MY RAZOR PAGE CSHTML

我的剃刀页面 CSHTML

@model MVCDemo.ViewModels.GradeSelectListViewModel
....
@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    ....
    @Html.DropDownListFor(x => Model.Employee.Level,
        new SelectList(Model.Grades, "ID", "Level"),
        "Select Level")
    ....
    <input type="submit" value="Create" class="btn btn-default" />
}

回答by

The main issue is that in the view you have new SelectList(Model.Grades, "ID", "Level")but Gradesis IEnumerable<SelectListItem>and SelectListItemdoes not contain properties named IDand Level.

主要的问题是,在视图中,您有new SelectList(Model.Grades, "ID", "Level"),但Grades就是IEnumerable<SelectListItem>SelectListItem不包含命名属性IDLevel

However there are a a few other issues with your code. First a view model should not contain a data model, and instead your view model should be

但是,您的代码还有一些其他问题。首先,视图模型不应该包含数据模型,而您的视图模型应该是

public class GradeSelectListViewModel
{
    public int? ID { get; set; } // make this ID so you do not need an input for it
    public string Name { get; set; }
    .... // other properties of Employee that your editing
    [Required(ErrorMessage = "..")]
    public int? Level { get; set; } // make value types nullable to protect against under-posting attacks
    public IEnumerable<SelectListItem> Grades { get; set; }
}

and add display and validation attributes as required. Note that I deleted the constructor (you don't seem to be using it, but if you did, then you also need to include a parameter-less constructor, otherwise an exception will be thrown when submitting to the POST method. I also assume that Levelshould be typeof intsince you binding to the int IDproperty of Grade.

并根据需要添加显示和验证属性。请注意,我删除了构造函数(您似乎没有使用它,但是如果您这样做了,那么您还需要包含一个无参数的构造函数,否则提交到 POST 方法时会抛出异常。我也假设这Level应该是的typeof int,因为您有约束力的int ID财产Grade

The the code in your GET method should be

GET 方法中的代码应该是

Employee employee = db.Employees.Find(id);
var model = new GradeSelectListViewModel()
{
    ID = employee.EmployeeID,
    Name = employee.Name,
    Level = employee.Level, // convert to int?
    ....
    Grades = db.Grades.Select(x => new SelectListItem
    {
        Value = x.ID.ToString(),
        Text = x.Level
    })
};
return View(model);

and in the view

并且在视图中

 @Html.DropDownListFor(x => Model.Level, Model.Grades, "Select Level")

Note also that in the POST method, your need to reassign the SelectListif you return the view because ModelStateis invalid.

另请注意,在 POST 方法中,SelectList如果您返回视图,ModelState则需要重新分配,因为无效。

回答by Murat Y?ld?z

You can use the following approach that populates three DropDownListFor at the same View:

您可以使用以下方法在同一视图中填充三个 DropDownListFor:

ViewModel:

视图模型:

public class GroupViewModel
{  
    public IEnumerable<SelectListItem> Schedules { get; set; }
    public int ScheduleId { get; set; }

    public IEnumerable<SelectListItem> Labs { get; set; }
    public int LabId { get; set; }

    public IEnumerable<SelectListItem> Terms { get; set; } 
    public int TermId { get; set; }
}



Controller:



控制器:

public ActionResult Create()
{
    //Populate DropDownList binding values
    var model = new GroupViewModel
    {
        //Preselect the Lab with id 2
        //LabId = 2,

        Labs = repository.Labs.Select(c => new SelectListItem
        {
            Value = c.Id.ToString(),
            Text = c.Name
        }),
        Terms = repository.Terms.Select(c => new SelectListItem
        {
            Value = c.Id.ToString(),
            Text = c.Name
        }),
        Schedules = repository.Schedules.Select(c => new SelectListItem
        {
            Value = c.Id.ToString(),
            Text = c.Name
        })
    };
    return View("Create", model);
}



View:



看法:

@Html.DropDownListFor(m => m.LabId, new SelectList(Model.Labs, "Value", "Text"), 
    "Select", new { @class = "selectpicker" })

@Html.DropDownListFor(m => m.ScheduleId, new SelectList(Model.Schedules, "Value", "Text"), 
    "Select", new { @class = "selectpicker" })

@Html.DropDownListFor(m => m.TermId, new SelectList(Model.Terms, "Value", "Text"), 
    "Select", new { @class = "selectpicker" })

Hope this helps...

希望这可以帮助...