开发者

Entity Framework and MVC3 Create and Update Model

开发者 https://www.devze.com 2023-03-10 04:41 出处:网络
So I\'ve used EF Code First to successfully create my entities and query the database to display the items.

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

精彩评论

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