歡迎來到《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)