MVC3 Entity Framework 4.1RC @Html.DropDownListFor 如何实际工作?

Posted

技术标签:

【中文标题】MVC3 Entity Framework 4.1RC @Html.DropDownListFor 如何实际工作?【英文标题】:MVC3 Entity Framework 4.1RC how does @Html.DropDownListFor actually work? 【发布时间】:2011-04-06 23:23:17 【问题描述】:

好的,我已经使用过 Google、*** 和 ASP.net - 我真的是唯一一个不明白这一点的人吗?

粗略的问题 = 我有一个引用 Office 实体的 Employee 实体。我以前可以创建新员工(因为我忘记了代码是如何工作的,所以我用锤子打败了我),但现在我无法创建员工也无法编辑现有员工。

现在,这是我学到的; 1) 确保在每一步都将办公室列表添加到 ViewBag 2) 这包括失败的 POST/编辑;调用函数以使用办公室列表重新填充 ViewBag 3)我认为(!!)你总是想设置 Employee.Office,而不是 Employee.Office.OfficeID;后者导致“是对象的关键信息的一部分,不能修改”的错误

所以,我所拥有的是;

具有以下方法的控制器;

    private void AddOfficesToViewBag()
    
        Dictionary<string, Office> list = new Dictionary<string, Office>();
        foreach (Office office in company.GetAllOffices())
            list.Add(office.ToString(), office);

        SelectList items = new SelectList(list, "Value", "Key");
        ViewBag.OfficeList = items;
    

创建一对看起来像;

    public ActionResult Create()
    
        if (company.Offices.Count() < 1)
            return RedirectToAction("Create", "Office", (object) "You need to create one or more offices first");

        AddOfficesToViewBag();
        return View(new Employee());
     

    //
    // POST: /Employee/Create

    [HttpPost]
    public ActionResult Create(Employee emp)
    

        if (TryUpdateModel<Employee>(emp))
        
            company.Employees.Add(emp);
            company.SaveChanges();
            return RedirectToAction("Index");
        
        else
        
            AddOfficesToViewBag();
            return View(emp);
        
    

还有一个看起来像这样的编辑对;

    public ActionResult Edit(int id)
    
        Employee emp = company.Employees.Single(e => e.EmployeeID == id);
        AddOfficesToViewBag();

        return View(emp);
    

    //
    // POST: /Employee/Edit/5

    [HttpPost]
    public ActionResult Edit(int id, FormCollection collection)
    
        Employee emp = company.Employees.Single(e => e.EmployeeID == id);

        if (TryUpdateModel(emp))
        

            company.SaveChanges();
            return RedirectToAction("Index");
        
        else
        
            AddOfficesToViewBag();
            return View(emp);
        
    

我将选择编辑视图,它与创建视图几乎相同;

@using (html.BeginForm()) @Html.ValidationSummary(true) 员工

    @Html.HiddenFor(model => model.EmployeeID)

    <div class="editor-label">
        @Html.LabelFor(model => model.Office)
    </div>
    <div class="editor-field">
       @Html.DropDownListFor(model => model.Office, (SelectList) ViewBag.OfficeList) 
       @Html.ValidationMessageFor(model => model.Office)
    </div>

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

    <div class="editor-label">
        @Html.LabelFor(model => model.Age)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Age)
        @Html.ValidationMessageFor(model => model.Age)
    </div>

    <p>
        <input type="submit" value="Save" />
    </p>
</fieldset>

我会说,特别是编辑,看起来几乎就在那里。它设法绑定到传入的 Employee 对象并将下拉列表设置为适当的条目。 查看原始 HTML 源代码显示输出值为 Office.ToString() 值。 对我来说奇怪的是,发生了一些魔术,将 Employee->Office 绑定到正确的条目,这使得 Edit 视图工作,但没有对所选项目进行相应的转换(字符串,又名 object->ToString() ) 到原始列表。

这看起来很基本(MVC / EF4 / DropDownList),我觉得我错过了一些非常基本的东西。

感谢所有想法。 问候 斯科特

【问题讨论】:

【参考方案1】:

根据以下你可以

http://forums.asp.net/t/1655622.aspx/1?MVC+3+Razor+DropDownListFor+and+Model+property+from+EFCodeFirst

执行以下操作:

[HttpPost]
public ActionResult Edit(Guid id, FormCollection collection)

        CollectionViewModel cvc = new CollectionViewModel();
        cvc.Collection = _db.Collections.Where(c => c.CollectionId == id).Include("CollectionType").First();
        Guid collectionTypeId = Guid.Parse(collection["CollectionTypeId"].ToString());
        cvc.Collection.CollectionType =_db.CollectionTypes.Where(ct =>ct.CollectionTypeId == collectionTypeId).First();

        if (TryUpdateModel(cvc))
        
            _db.SaveChanges();
            return RedirectToAction("Index");
        

视图模型

public class CollectionViewModel

      public Collection Collection get; set; 
      public Guid CollectionTypeId  get; set; 
      public SelectList CollectionTypes  get; set; 

【讨论】:

以上是关于MVC3 Entity Framework 4.1RC @Html.DropDownListFor 如何实际工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Entity Framework 4.1 与 MVC 3 登录一起使用

如何在 Entity Framework 4.1 中使用更新 SPROC

Entity Framework 4.1 - 动态预加载

Entity Framework 4.1 两个跟踪查询

Entity Framework 4.1 InverseProperty 属性和ForeignKey

Entity Framework 4.1 Fluent API 属性