实体框架和MVC3创建和更新模型

时间:2011-06-04 16:05:03

标签: c# asp.net asp.net-mvc-3 entity-framework-4 ef-code-first

所以我使用EF Code First成功创建我的实体并查询数据库以显示项目。

我现在想提供一种编辑记录的方法。

我有一个包含以下内容的Post类:

(TypeName = "varchar")]
[Required()]
public string Headline { get; set; }

public virtual PostType PostType { get; set; }

PostType是我写的一个类,它有一个ID和Name来将帖子分类为新闻,博客等。

现在,在我的编辑控制器中,我收到帖子并将其传递给视图模型中的视图。我也得到了不同帖子类型的IEnumerable。

在我看来,我使用以下内容:

<div class="formFieldContainer">
    @Html.LabelFor(model => model.Post.PostType)
    @Html.DropDownListFor(model => model.Post.PostType, new SelectList(Model.PostTypes, "ID", "Name"))
    @Html.ValidationMessageFor(model => model.Post.PostType)
</div>

<div class="formFieldContainer">
    @Html.LabelFor(model => model.Post.Headline)
    @Html.EditorFor(model => model.Post.Headline)
    @Html.ValidationMessageFor(model => model.Post.Headline)
</div>

在我的编辑控制器上,我有以下处理帖子:

[HttpPost, ValidateAntiForgeryToken, ValidateInput(false)]
public ActionResult Edit(int id, FormCollection collection) {
    var model = new PostViewModel();
    model.Post = _pr.GetPost(id); //gets the post from my post repository
    model.PostTypes = _ptr.GetPostTypes();

    try {
        UpdateModel(model.Post, "Post");
        _pr.Save();
        return RedirectToRoute("Posts", new { pageNumber = 0 }); //for now go to the homepage
    } catch (Exception e) {
        ModelState.AddModelError("_FORM", e.Message);
        return View(model);
    }
}

现在没有帖子类型列表,只有标题可行。但是对于帖子类型它没有。我得到“1无效”(1是选择列表的值),这是有道理的,因为我的Post模型需要PostType对象,而不是int。

我想做类似的事情:

model.Post.PostType = model.PostTypes.Where(x => x.ID == Int32.Parse(collection.GetValues("Post.PostType")[0])).Select(p => p).FirstOrDefault();

但是1)它不起作用所以它显然不是正确的方式和2)因为“Post.PostType”仍然存在,UpdateModel失败。

关于如何做到这一点的任何想法?

2 个答案:

答案 0 :(得分:1)

我假设您的存储库_pr和_ptr使用不同的上下文?实体框架必须从相同的上下文中读取和更新。由于您从另一个上下文获取post类型,因此EF将其视为新实体,因此数据库中会有额外的行。

您应该在存储库之间共享您的上下文,每个请求的会话是事实上的最佳实践。

对于更新模型函数,您可以传入一个字符串数组属性以包含在更新中:

UpdateModel(model.Post, "Post", new string[] { "Headline" });

这将忽略PostType值。

答案 1 :(得分:1)

尝试更改您的操作以接收Post对象:

public ActionResult Edit(Post post) {

使用MVC 3,EF 4,post对象应该从表单变量中填充,包括PostType。然后调用您的更新并保存方法。