zoukankan      html  css  js  c++  java
  • 博客园现代化建设—用 Entity Framework 与 Json.NET 实现数据的按需更新

    上篇随笔中,我们留下了一个难题——如何将客户端浏览器通过ajax提交的json数据传递给一个已存在的实体对象(也就是将json数据赋值给实体对象对应的属性)。这样的话,Entity Framework就能自动发现哪些属性值发生了变化,在保存时,只将发生变化的属性值更新至对应的数据库字段。

    需要注意的是这里提交的json数据中的属性是动态的,不一定包含实体对象的所有属性,比如:这次提交的是{"Title":"Hello World"},下次提交的是{"Title":"Hello World","Description":"This is a test."}。第一种情况对应的应用场景是,博客后台提供一个快速修改标题的功能,通过弹出层弹出一个修改标题的文本框完成修改。

    在这里再强调一下Entity Framework如何实现按需更新。先给它一个修改前的实体对象,然后修改当前这个对象的属性值,EF才能跟踪所做的修改,并在保存时更新至数据库。

    面对这个难题,你也许想到了这样一种方法。直接将json数据反序列化为实体对象(ASP.NET MVC的控制器可以自动完成这个反序列化),然后将这个对象的属性值复制给EF跟踪的实体对象。但是,你不知道这个反序列化出来的对象的哪些属性值是来自json数据的。全部复制也不可行,前面已经说明过json数据中的属性是动态的,这个反序列化出来的对象并不是完整的实体对象。如果强行全部复制,更新时,会造成json数据中未包含的属性的数据丢失。

    我们采用的解决方法是:通过Json.NET获取json数据中的属性,然后通过反射去修改被EF跟踪的实体对象的对应的属性值。

    下面我们通过代码示例说明一下我们的解决方法。

    客户端浏览器中通过ajax提交json数据的js代码:

    function update_post() {
    var post = {};
    post.Title
    = $.trim($("#txtTitle").val());
    post.Description
    = $.trim($("#txtDescription").val());
    var jsonStr = JSON.stringify(post);
    var entry = {};
    entry.postId
    = entryId;
    entry.jsonData
    = jsonStr;
    $.ajax({
    url:
    '/admin/AjaxUpdatePost.aspx',
    data: JSON.stringify(entry),
    success: update_post_callback
    });
    }

    实际提交的json数据:

    {"postId":3560,"jsonData":"{\"Title\":\"hello world\",\"Description\":\"test\"}"}

    ASP.NET MVC Controller中的代码:

    [HttpPost]
    public JsonResult AjaxUpdatePost(int postId, string jsonData)
    {
    return Json(ServiceFactory.BlogEntryService.Update(postId, jsonData));
    }
    代码很简单,只是对服务层的调用,然后服务器层再去调用业务逻辑层。

    业务逻辑层中的代码:

    public class BlogEntryManager
    {
    //实体对象数据更新
    public bool Update(int postId, string jsonData)
    {
    BlogPost originalPost
    = GetBlogPost(postId);
    using (BlogDbContext context = new BlogDbContext())
    {
    context.BlogPosts.Attach(originalPost);
    JsonToObject(originalPost, jsonData);
    context.SaveChanges();
    }
    return true;
    }
    //Json数据复制给实体对象
    private void JsonToObject(BlogPost post, string jsonData)
    {
    JObject jo
    = JObject.Parse(jsonData);
    var postType
    = post.GetType();
    foreach (var proper in jo.Properties())
    {
    postType.GetProperty(proper.Name).SetValue(post, (
    string)proper.Value, null);
    }
    }
    //获取修改前的实体对象
    public BlogPost GetBlogPost(int entryId)
    {
    using (BlogDbContext context = new BlogDbContext())
    {
    var result
    = from p in context.BlogPosts
    where p.ID == entryId && p.IsExist
    select p;
    return result.FirstOrDefault();
    }
    }
    }

    代码通过测试,已经验证了能够满足我们目前的需求。

    博客园现代化建设又向前迈进了一步!

  • 相关阅读:
    两个路由器配置静态路由只能单边 ping 通
    CVE202125646:Apache Druid远程命令执行漏洞复现
    批量修改图片的格式
    十大远程控制软件排名
    Splashtop 免费60天 大赠送
    单例设计模式
    蓄水池抽样算法/水塘采样算法
    kafka安装(单机版)
    LeetCode382链表随机节点
    LeetCode398随机数索引
  • 原文地址:https://www.cnblogs.com/dudu/p/entity_framework_json_net.html
Copyright © 2011-2022 走看看