所以我使用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失败。
关于如何做到这一点的任何想法?
答案 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。然后调用您的更新并保存方法。