开发者

Entity Framework and MVC3 Create and Update Model

So I've used EF Code First to successfully create my entities and query the database to display the items.

I now want to provide a way to edit the records.

I have a Post class which contains:

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

public virtual PostType PostType { get; set; }

PostType is a class I wrote which has an ID and Name to categorise posts into News, Blog etc.

Now, in my Edit controller I get the post and pass this to the view in a view model. I also get a IEnumerable of the different post types.

In my view I use the below:

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

On my edit controller I have the below to handle the post:

[HttpPost, ValidateAn开发者_运维技巧tiForgeryToken, 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);
    }
}

Now without the post type list and just the headline this works. However with the post type it doesn't. I get "1 is invalid" (1 being the value of the select list) which makes sense as my Post model expects a PostType object, not int.

I thought about doing something like:

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

But 1) it doesn't work so its obviosuly not the right way and 2) since "Post.PostType" still exists, the UpdateModel fails.

Any ideas on how to do this?


I assume your repositories _pr and _ptr are using different contexts? Entity framework must read and update from the same context. Since you are getting the post types from another context EF treats it as a new entity hence the extra row in your database.

You should share your context between repositories, session per request is a defacto best practice.

As for the update model function you can pass in a string array of properties to include in the update:

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

This will ignore the PostType value.


Try changing your action to take in a Post object:

public ActionResult Edit(Post post) {

With MVC 3, EF 4, the post object should be populated from the form vars, including your PostType. Then call your update and save methods.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜