简体   繁体   English

根据输入数据更新Entity Framework中的行

[英]Update row in Entity Framework based on input data

I have a very simple form. 我有一个非常简单的表格。 I am collecting Employee Name and DepartmentName from that form as shown below. 我正在从该表单中收集“雇员姓名”和“部门名称”,如下所示。 I also have a hidden input which is named StatusID. 我也有一个名为StatusID的隐藏输入。 Users are not able to see and enter any data in it. 用户无法查看和输入任何数据。 However i would like to update this StatusID based on data from DepartmentName input. 但是我想根据DepartmentName输入的数据更新此StatusID。 Let say if DepartmentName is IT then i would like to insert "1" to StatusID row. 可以说,如果DepartmentName是IT,那么我想在StatusID行中插入“ 1”。 If the departmentName is HR, StatusID will be updated as "2". 如果部门名称为HR,则StatusID将更新为“ 2”。

I tried many ways to achieve this but not able to do so. 我尝试了许多方法来实现这一目标,但未能做到。

Any idea how i can achieve it? 任何想法我怎么能做到?

@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

<fieldset>
    <legend>Employee</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.Name)
    </div>
    <div class="editor-field">
        @Html.TextBoxFor(model => model.Name)
    </div>
    <div class="editor-label">
        @Html.LabelFor(model => model.DepartmentName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.DepartmentName)
    </div>

    <div class="editor-field">
        @Html.HiddenFor(model => model.StatusID)
    </div>
    <input type="submit" value="Create" />
 </fieldset>

And this is my controller for Create. 这是我创建的控制器。

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Employee employee)
    {
        if (ModelState.IsValid)
        {
            db.Employee.Add(employee);
            db.SaveChanges();

            return RedirectToAction("Index");
        }

        return View(employee);
    }

And this is my Class: 这是我的课:

  public partial class Employee
{
    public int EmployeeID { get; set; }
    public string Name { get; set; }
    public string DepartmentName{ get; set; }
    public int StatusID { get; set; }
}

您可以为其创建枚举,并根据部门的状态ID检查枚举条目,可以为此使用转换器

Is there a specific reason that you need to set StatusID in your view, can you not just do it as part of your controller method? 是否有特定的原因需要在视图中设置StatusID,难道您不就可以将它设置为控制器方法的一部分吗?

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Employee employee)
{
    if (ModelState.IsValid)
    {
        switch (employee.DepartmentName)
        {
            case "IT":
                employee.StatusID = 1
                break;
            case "HR":
                employee.StatusID = 2
                break;
            default:
                employee.StatusID = 1
                break;
        }

        db.Employee.Add(employee);
        db.SaveChanges();

        return RedirectToAction("Index");
    }

    return View(employee);
}

Of course you can change from a switch statement to a ternary operator if you only ever want to check between values of 1 and 2 当然,如果您只想在值1和2之间进行检查,则可以从switch语句更改为三元运算符。

Thus StatusID depends on DepartmentName and this logic belongs to Employee class, you can set StatusID when setting DepartmentName : 因此, StatusID取决于DepartmentName并且此逻辑属于Employee类,可以在设置DepartmentName时设置StatusID

private string deparmentName;

public string DepartmentName
{ 
   get { return deparmentName; }
   set 
   {
       deparmentName = value;

       switch(deparmentName)
       {
          case "IT" : StatusID = 1; break;
          case "HR" : StatusID = 2; break;
          default: 
              StatusID = 0; break;
       }
   }
}

Keep in mind, that user can input data not only in upper case. 请记住,该用户不仅可以输入大写字母,还可以输入数据。 Consider also using enum for departments: 还考虑对部门使用enum

public enum Department
{
    None = 0,
    IT = 1,
    HR = 2
}

And use single property of this enum type instead of two properties for department name and status id: 并使用此枚举类型的单个属性,而不是部门名称和状态ID的两个属性:

public partial class Employee
{
    public int EmployeeID { get; set; }
    public string Name { get; set; }
    public Department Department { get; set; }
}

You could also define your own ModelBinder to map those properties the way you want : 您还可以定义自己的ModelBinder以所需的方式映射这些属性:

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        object model = bindingContext.Model;
        Employee employee = (Employee)model;
        if (employee == null)
        {
            employee = new Employee();
        }
        string departnementName = "DepartmentName";

        var departnementNameValue = bindingContext.ValueProvider.GetValue(departnementName);

        try
        {
            if (departnementName == "IT")
            {
                employee.StatusID = 1;
            }
        }
        catch (Exception ex)
        {
            bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex.Message);
            bindingContext.ModelState.SetModelValue(departnementName, departnementNameValue);
        }
        return employee;
    }

If else or switch statement? 否则还是用switch声明?

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Employee employee)
{
    if (ModelState.IsValid)
    {
        if(employee.DepartmentName == "IT")
        {
           employee.StatusID == 1;
        }
        else if(employee.DepartmentName == "HR")
        {
           employee.StatusID == 2;
        }
        else
        {
           employee.StatusID == 1;
        }
        db.Employee.Add(employee);
        db.SaveChanges();            

        return RedirectToAction("Index");
    }

    return View(employee);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM