webentwicklung-frage-antwort-db.com.de

Füllen Sie DropDownList in ASP.NET MVC aus der Datenbanktabelle mit Entity Framework 6 und ViewModel auf

Ich habe mir eine ganze Nacht lang den Kopf über ein Problem gekratzt, das ich schnell mit Ajax/Jquery und gespeicherten Prozeduren lösen kann. Ich möchte 

1) Füllen Sie eine Dropdown-Liste mit Werten aus einer Datenbanktabelle, die Entity Framework und das Ansichtsmodell verwenden. Ich möchte VIEWBAG OR VIEWDATA NICHT VERWENDEN. Jede Hilfe geschätzt.

2) Wie kann ich eine Ansicht erstellen, indem das Ansichtsmodell mit allen Standardfeldern verwendet wird? Das Gerüst arbeitet an einem Modell, aber nicht an einem Sichtmodell?

MEINE MODELLE

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

Modell anzeigen

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

MEINE KONTEXTKLASSE

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

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

MEINE RAZOR-SEITE 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" />
}
4
TropicalViking

Das Hauptproblem ist, dass in der Ansicht new SelectList(Model.Grades, "ID", "Level") vorhanden ist, Grades jedoch IEnumerable<SelectListItem> ist und SelectListItem keine Eigenschaften mit den Namen ID und Level enthält.

Es gibt jedoch einige andere Probleme mit Ihrem Code. Zunächst sollte ein Ansichtsmodell kein Datenmodell enthalten, und stattdessen sollte es Ihr Ansichtsmodell sein

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

und fügen Sie nach Bedarf Anzeige- und Validierungsattribute hinzu. Beachten Sie, dass ich den Konstruktor gelöscht habe (Sie scheinen ihn nicht zu verwenden, aber wenn dies der Fall ist, müssen Sie auch einen parameterlosen Konstruktor hinzufügen. Andernfalls wird beim Senden an die Methode POST eine Ausnahme ausgelöst.) Ich gehe auch davon aus, dass Level typeof int sein sollte, da Sie an die int ID-Eigenschaft von Grade gebunden werden.

Der Code in Ihrer GET-Methode sollte sein

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

und in der Ansicht

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

Beachten Sie auch, dass Sie in der Methode POST die Variable SelectList neu zuweisen müssen, wenn Sie die Ansicht zurückgeben, da ModelState ungültig ist.

7
user3559349

Sie können den folgenden Ansatz verwenden, der drei DropDownListFor in derselben View auffüllt:

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



Aussicht:

@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" })

Hoffe das hilft...

1
Murat Yıldız