【原创】基于.NET的轻量级高性能 ORM – TZM.XFramework 之优雅增删改

  • 2019 年 11 月 7 日
  • 筆記

 【前言】

  大家好,我是TANZAME。出乎意料的,我们在立冬的前一天又见面了,天气慢慢转凉,朋友们注意添衣保暖,愉快撸码。距离 TZM.XFramework 的首秀已数月有余,期间收到不少朋友的鼓励、建议和反馈,在此致以深深的感谢。

  不少围观的朋友经常问题我,.NET 体系下优秀的 O/RM 官方的有EF,第三方的有linq2db (国外)、StackExchange/Dapper (国外)、NHibernate (国外)、PetaPoco (国外)、Freesql (国内)等等,What’s your problem?Ok,咱们就用一分钟的时间聊聊 What’s my Advantage,聊聊如何用 ORM 优雅的进行增删改。

 【正文】

  相信朋友们都遇到过这样的场景:要插入/删除/修改的数据来自外键表,怎么办?先查出来再进行接下的操作吗,别这样老铁,至少两次以上的数据库访问会让有洁癖的你感到“菊”部瘙痒。手撸纯 SQL吗,看起来还行至少不会那么令人不舒服。如果有 ORM 能帮我们撸这种 SQL,岂不更痛快?来看看我们的 ORM 是怎么操作的:

  1. 多表关联更新  

// 更新本表值等于别表的字段值  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. 多表关联删除

// 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 

【结语】

  经过大半月的努力,TZM.XFramework 也已正式支持 SQLite了,托管地址:GitHub托管地址:https://github.com/TANZAME/XFramework 。最后借用某公众号上面的一句话与大家共勉,有趣和好奇心是为了取悦自己,然后才能有意思和有用是去取悦别人。撸码不易,不喜轻喷,有不同看法老友欢迎加群交流。

  技术交流群:816425449