【前言】html
你們好,我是TANZAME。出乎意料的,咱們在立冬的前一天又見面了,天氣慢慢轉涼,朋友們注意添衣保暖,愉快擼碼。距離 TZM.XFramework 的首秀已數月有餘,期間收到很多朋友的鼓勵、建議和反饋,在此致以深深的感謝。git
很多圍觀的朋友常常問題我,.NET 體系下優秀的 O/RM 官方的有EF,第三方的有linq2db (國外)、StackExchange/Dapper (國外)、NHibernate (國外)、PetaPoco (國外)、Freesql (國內)等等,What's your problem?Ok,我們就用一分鐘的時間聊聊 What's my Advantage,聊聊如何用 ORM 優雅的進行增刪改。github
【正文】sql
相信朋友們都遇到過這樣的場景:要插入/刪除/修改的數據來自外鍵表,怎麼辦?先查出來再進行接下的操做嗎,別這樣老鐵,至少兩次以上的數據庫訪問會讓有潔癖的你感到「菊」部瘙癢。手擼純 SQL嗎,看起來還行至少不會那麼使人不舒服。若是有 ORM 能幫咱們擼這種 SQL,豈不更痛快?來看看咱們的 ORM 是怎麼操做的:數據庫
1. 多表關聯更新 app
// 更新本表值等於別表的字段值 var query = from a in context.GetTable<Model.Client>() join b in context.GetTable<Model.CloudServer>() on a.CloudServerId equals b.CloudServerId join c in context.GetTable<Model.ClientAccount>() on a.ClientId equals c.ClientId where c.AccountId == "1" select a; context.Update<Model.Client, Model.CloudServer, Model.ClientAccount>((a, b, c) => new { CloudServerId = b.CloudServerId, Qty = c.Qty > 0 ? c.Qty : 1, }, query); context.SubmitChanges(); -- 產生的SQL --UPDATE t0 SET --t0.[CloudServerId] = t1.[CloudServerId] --FROM [Bas_Client] AS [t0] --INNER JOIN [Sys_CloudServer] t1 ON t0.[CloudServerId] = t1.[CloudServerId] --INNER JOIN [Bas_ClientAccount] t2 ON t0.[ClientId] = t2.[ClientId] --WHERE t2.[AccountId] = @p0 --UPDATE t0 SET --t0.[CloudServerId] = t1.[CloudServerId], --t0.[Qty] = (CASE WHEN t2.[Qty] > @p1 THEN t2.[Qty] ELSE @p2 END) --FROM [Bas_Client] AS [t0] --INNER JOIN [Sys_CloudServer] t1 ON t0.[CloudServerId] = t1.[CloudServerId] --INNER JOIN [Bas_ClientAccount] t2 ON t0.[ClientId] = t2.[ClientId] --WHERE t2.[AccountId] = @p3
2. 多表關聯插入性能
// 多表關聯批量新增 var query = from a in context.GetTable<Model.Client>() join b in context.GetTable<Model.CloudServer>() on a.CloudServerId equals b.CloudServerId where a.ClientId <= 5 && b.CloudServerId != 0 select new Model.Client { ClientId = DbFunction.RowNumber<int>(x => a.ClientId) + (maxClientId + 2), ClientCode = "ABC2", ClientName = "啊啵呲2", CloudServerId = b.CloudServerId, State = 2, ActiveDate = DateTime.Now }; context.Insert(query); -- 產生的SQL --INSERT INTO [Bas_Client]([ClientId],[ClientCode],[ClientName],[CloudServerId],[State],[ActiveDate]) --SELECT --ROW_NUMBER() Over(Order By t0.[ClientId]) + @p17 + @p18 AS [ClientId], --@p19 AS [ClientCode], --@p20 AS [ClientName], --t1.[CloudServerId] AS [CloudServerId], --@p21 AS [State], --@p22 AS [ActiveDate] --FROM [Bas_Client] t0 --INNER JOIN [Sys_CloudServer] t1 ON t0.[CloudServerId] = t1.[CloudServerId] --WHERE t0.[ClientId] <= @p23 AND t1.[CloudServerId] <> @p24
3. 多表關聯刪除spa
// Query 關聯批量刪除
var query =
from a in context.GetTable<Model.Client>()
join b in context.GetTable<Model.ClientAccount>() on a.ClientId equals b.ClientId
join c in context.GetTable<Model.ClientAccountMarket>() on new { b.ClientId, b.AccountId } equals new { c.ClientId, c.AccountId }
where c.ClientId > 100 && c.AccountId == "1" && c.MarketId == 1
select a;
context.Delete<Model.Client>(query1);
-- 產生的SQL
--DELETE t0 FROM [Bas_Client] t0
--INNER JOIN [Bas_ClientAccount] t1 ON t0.[ClientId] = t1.[ClientId]
--INNER JOIN [Bas_ClientAccountMarket] t2 ON t1.[ClientId] = t2.[ClientId] AND t1.[AccountId] = t2.[AccountId]
--WHERE t2.[ClientId] > @p2 AND t2.[AccountId] = @p3 AND t2.[MarketId] = @p4
【結語】hibernate
通過大半月的努力,TZM.XFramework 也已正式支持 SQLite了,託管地址:GitHub託管地址:https://github.com/TANZAME/XFramework 。最後借用某公衆號上面的一句話與你們共勉,有趣和好奇心是爲了取悅本身,而後纔能有意思和有用是去取悅別人。擼碼不易,不喜輕噴,有不一樣見解老友歡迎加羣交流。htm
技術交流羣:816425449