天天看點

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)
           

系列文章導航

  • (一)什麼是倉儲
  • (二)如何使用倉儲
  • (三)實體特性
  • (四)工作單元
  • (五)狀态管理
  • (六)導航屬性
  • (七)多表查詢
  • (八)級聯加載
  • (九)級聯儲存
  • (十)動态實體類型
  • (十一)分表
  • (十二)如何擴充

繼續閱讀