zoukankan      html  css  js  c++  java
  • FreeSql.Repository (五)状态管理

    欢迎来到《FreeSql.Repository 仓储模式》系列文档,本系列文档专注介绍 【仓储+工作单元】 的使用方式。完整文档请前往 wiki 中心:https://github.com/dotnetcore/FreeSql/wiki

    相信很多做过 ORM 的同学都有一个难题,关于更新数据的问题,一般都是按对象为单位做更新 API,比如:

    var item = new Song();
    item.Id = 1;
    orm.Update(item);
    

    问题来了,每次都更新全部字段?强迫症的人受不了,更新全部字段的缺点:

    • 对象数据不完整,比如 item.UpdateTime 没有值不需要更新;
    • 性能问题,试想如果一个表有30个字段,每次操作会产生庞大的 SQL 语句,数据库执行的效率也低下;

    状态管理

    我见过有些 ORM 是通过属性通知做的,对属性赋值后会记录状态,最终更新对象的时候就知道哪些属性是变化过的,缺点是对实体类有一定入侵。

    FreeSql.Repository 实现了对象的状态管理,对实体类没有入侵,原理是在仓储中存有一个对象副本,在最终更新对象的时候与副本对比,从而得到变化的属性。

    案例1:先查询,更新只变化的字段

    var repo = fsql.GetRepository<Song>();
    var item = repo.Where(a => a.Id == 1).First();  //此时快照 item
    item.Title = "newtitle";
    repo.Update(item); //对比快照时的变化
    //UPDATE `Song` SET `Title` = @p_0
    //WHERE (`Id` = 1)
    

    案例2:更新时没有变化,则不更新

    var item = repo.Where(a => a.Id == 1).First();  //此时快照 item
    repo.Update(item); //对比快照时的变化,没有变化不执行 SQL
    

    案例3:不查询,直接使用状态管理更新

    var item = new Song { Id = 1 };
    repo.Attach(item); //此时快照 item
    item.Title = "newtitle";
    repo.Update(item); //对比快照时的变化
    //UPDATE `Song` SET `Title` = @p_0
    //WHERE (`Id` = 1)
    

    系列文章导航

  • 相关阅读:
    psi
    firefox修改语言
    automapper
    堆喷图解
    脱壳系列_0_FSG壳_详细版
    脱壳系列_1_UPX壳_详细版
    算法01-最大子数组详解
    逆向MFC程序
    如何执行shell命令
    Unity之流光效果
  • 原文地址:https://www.cnblogs.com/FreeSql/p/14118461.html
Copyright © 2011-2022 走看看