在实体框架中编辑对象并将其保存到ASP.NET MVC 2.0中的数据库 [英] Editing an object in entity framework and saving it to the database in ASP.NET MVC 2.0

查看:100
本文介绍了在实体框架中编辑对象并将其保存到ASP.NET MVC 2.0中的数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我知道EF实体跟踪自己的变化,并在调用保存更改时将它们保留到数据库,但是这种情况如何...

我有一个旨在编辑博客文章的页面。它有两种操作方法。

  [HttpGet] 
public ViewResult EditBlogPost(int Id)
{
//此操作方法通过ID获取博客文章,并返回编辑博客帖子页。
BlogPost blogPost = db.BlogPosts.Where(x => x.Id == Id).FirstOrDefault();
if(blogPost == null)
{
ViewData [message] =未找到博客帖子;
return View(Result);
}
return View(ManageBlogPost,blogPost);
}

[HttpPost]
public ViewResult EditBlogPost(BlogPost blogPost)
{
//这是我遇到的问题。当模型绑定填充blogPost时,是否自动跟踪?由于某些原因,SaveChanges()似乎不会保留更新。
if(!ModelState.IsValid)
return View(ManageBlogPost);
db.AttachTo(BlogPosts,blogPost); //我试过这个方法,似乎是我想要的,但是没有帮助。
db.SaveChanges();
ViewData [message] =博客文章已成功编辑。
return View(Result);
}

这是这些返回的视图:

 <%@ Page Title =Language =C#MasterPageFile =〜/ Views / Shared / Master.MasterInherits =System.Web。 Mvc.ViewPage< BlogProject.Models.BlogPost>中%GT; 

< asp:Content ID =Content1ContentPlaceHolderID =MainContentrunat =server>

<%if(Model!= null)
{%>
< h2>编辑博客文章< / h2>
<%}
else
{%>
< h2>添加博客帖子< / h2>
<%}%>
<%using(Html.BeginForm())
{%>
<%if(Model!= null)
{%>
<%:Html.HiddenFor(x => x.Id)%> <! - 这是保持编辑窗体隐藏的不可编辑数据的方法,并在下一个模型绑定时重新填充它们?如果有人用像Fiddler这样的东西来修改他们的POST呢?在POST之前他们不能理论上编辑这些字段? - >
<%:Html.HiddenFor(x => x.Date)%>
<%:Html.HiddenFor(x => x.Author)%>
<%:Html.HiddenFor(x => x.FriendlyUrl)%>
<%}%>
标题:< br />
<%:Html.TextBoxFor(x => x.Title,new {Style =Width:90%;})%>
< br />
< br />
摘要:< br />
<%:Html.TextAreaFor(x => x.Summary,new {Style =Width:90%; Height:50px;})%>
< br />
< br />
正文:< br />
<%:Html.TextAreaFor(x => x.Body,new {Style =Height:250px; Width:90%;})%>
< br />
< br />
< input type =submitvalue =提交/>
<%}%>

< / asp:Content>

我在这里有些困惑。添加博客帖子似乎工作正常,但编辑它们是另一个故事。

解决方案

解决方案不是在博客文章中编辑操作方法中的对象。相反,做一些这样的事情:

  [HttpPost] 
public ViewResult EditBlogPost(int postID)
{
var post = db.BlogPosts.Single(p => p.PostID = postID);
TryUpdateModel(post);

if(!ModelState.IsValid)
return View(ManageBlogPost);

db.SaveChanges();

ViewData [message] =博客文章已成功编辑。
return View(Result);
}

这样一来,对象被附加到上下文,EF可以正确跟踪变化。 UpdateModel 方法是一种时间保护程序,可自动将表单集合中的字段与模型中的字段进行匹配,并为其更新。



以下是 UpdateModel 的文档:
MSDN


So I know that EF entities track their own changes and persist them to the database when savechanges is called, but what about this scenario...

I have a page that is designed to edit a blog post. It has two action methods.

    [HttpGet]
    public ViewResult EditBlogPost(int Id)
    {
        //This action method gets the blog post by the id and returns the edit blog post page.
        BlogPost blogPost = db.BlogPosts.Where(x => x.Id == Id).FirstOrDefault();
        if (blogPost == null)
        {
            ViewData["message"] = "Blog post not found.";
            return View("Result");
        }
        return View("ManageBlogPost", blogPost);
    }

    [HttpPost]
    public ViewResult EditBlogPost(BlogPost blogPost)
    {
        //This one is where I'm having issues. When model binding populates blogPost, is it auto-tracking still? For some reason SaveChanges() doesn't seem to persist the updates.
        if (!ModelState.IsValid)
            return View("ManageBlogPost");
        db.AttachTo("BlogPosts", blogPost); //I tried this method, it seemed to be what I wanted, but it didn't help.
        db.SaveChanges();
        ViewData["message"] = "Blog post edited successfully.";
        return View("Result");
    }

Here is the view that these return:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Master.Master" Inherits="System.Web.Mvc.ViewPage<BlogProject.Models.BlogPost>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">

    <% if (Model != null)
       { %>
            <h2>Edit Blog Post</h2>
    <% }
       else
       { %>
            <h2>Add Blog Post</h2>
    <% } %>
    <% using (Html.BeginForm())
       { %>
            <% if (Model != null)
               { %>
                    <%: Html.HiddenFor(x => x.Id)%> <!-- Is this the way to keep un-editable data hidden from the edit form and have them repopulate on the next model bind? What if someone went to modify their POST using something like Fiddler? Couldn't they theoretically edit these fields before the POST? -->
                    <%: Html.HiddenFor(x => x.Date) %>
                    <%: Html.HiddenFor(x => x.Author) %>
                    <%: Html.HiddenFor(x => x.FriendlyUrl) %>
            <% } %>
            Title:<br />
            <%: Html.TextBoxFor(x => x.Title, new { Style = "Width: 90%;" })%>
            <br />
            <br />
            Summary:<br />
            <%: Html.TextAreaFor(x => x.Summary, new { Style = "Width: 90%; Height: 50px;" }) %>
            <br />
            <br />
            Body:<br />
            <%: Html.TextAreaFor(x => x.Body, new { Style = "Height: 250px; Width: 90%;" })%>
            <br />
            <br />
            <input type="submit" value="Submit" />
    <% } %>

</asp:Content>

I'm a little confused here. Adding blog posts seems to work fine, but editing them is another story.

解决方案

The solution is not to take in the blog post object in your edit action method. Instead, do something that looks like this:

[HttpPost]
public ViewResult EditBlogPost(int postID)
{
    var post = db.BlogPosts.Single(p => p.PostID = postID);
    TryUpdateModel(post);

    if (!ModelState.IsValid)
        return View("ManageBlogPost");

    db.SaveChanges();

    ViewData["message"] = "Blog post edited successfully.";
    return View("Result");
}

This way the object is attached to the context and the EF can track changes properly. The UpdateModel method is a time saver that automatically matches fields in the form collection to the fields in the model and updates them for you.

Here is the documentation for UpdateModel: MSDN

这篇关于在实体框架中编辑对象并将其保存到ASP.NET MVC 2.0中的数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆