高效能資料匯入方案&表過濾器&一對多支援篩選- .NET SqlSugar ORM

果糖大資料科技發表於2021-01-31

一、資料匯入有哪些難題

該功能可以說100%的開發人員都會遇到,並且非常的常見,比如批量操作,你知道哪條資料錯了嗎?

你都不知道客戶更不知道了

 

1、資料分類

   你需要將 插入、更新、忽略不計、錯誤資料 等進麼分類彙總,最後返回給客戶,如果沒有很好的設計想把這些操作一步到位非常的難

2、高效能

   對於插入或者更新 肯定不能單純的插入或者更新,一定要批量操作,或者用到blukcopy操作

3、資料驗證

   對於錯誤資料要進行組裝 ,並返回客戶,讓客戶知道哪些欄位 哪個資料出現錯誤

 

二、使用 Storageable 解決難題

我們可以使用SqlSugar ORM中的 Storageable功能來解決上面的幾大難題 ,SqlSugar 作為老牌ORM框架一直在創新和更新

 

1、入門示例

如何用Storageable實現簡單的插入或者更新

例題1:匯入一個List ,當id等0插入, id>0執行更新 (id是主鍵 )

List<UinitBlukTable> list2 = new List<UinitBlukTable>();
list2.Add(new UinitBlukTable() { Id = 1, Name = "a", Create = DateTime.Now });
list2.Add(new UinitBlukTable() { Id = 2, Name = "a", Create = DateTime.Now });
list2.Add(new UinitBlukTable() { Id = 0, Name = "a", Create = DateTime.Now });

var x = Db.Storageable(list2)
.SplitUpdate(it => it.Item.Id > 0)
.SplitInsert(it => it.Item.Id == 0).ToStorage();
x.AsInsertable.ExecuteCommand();
x.AsUpdateable.ExecuteCommand();

  

例題2:匯入一個LIST,當Id存在資料庫執行更新,否則執行插入

var x = Db.Storageable(list2)
                            .SplitUpdate(it => it.Any(y=>y.Id==it.Item.Id))//資料庫存在更新
                            .SplitInsert(it => true ).ToStorage();//其餘插入
                            x.AsInsertable.ExecuteCommand(); //也可以使用blukcopy  參考SqlSugar blukcopy用法
                            x.AsUpdateable.ExecuteCommand();  

如果實體沒有主鍵我們可以用

var x = Db.Storageable(list2)
                            .SplitUpdate(it => it.Any(y=>y.Id==it.Item.Id))
                            .SplitInsert(it => it.NotAny(y => y.Id == it.Item.Id))
                            .WhereColumns(it=>it.Id).ToStorage(); //以id作為資料庫唯一列,當然支援多個 new {it.id,it.name}

  

2.資料驗證和統計

準備4條測試資料

List<UinitBlukTable> list2 = new List<UinitBlukTable>();
list2.Add(new UinitBlukTable() { Id = 1, Name = "a", Create = DateTime.Now });
list2.Add(new UinitBlukTable() { Id = 2, Name = "a", Create = DateTime.Now });
list2.Add(new UinitBlukTable() { Id = 3, Name = "a", Create = DateTime.Now.AddYears(-2) });
list2.Add(new UinitBlukTable() { Id = 4, Name ="", Create = DateTime.Now.AddYears(-2) });

編寫程式碼將錯誤資料、可插入資料、可更新資料等進行分類  

var x = Db.Storageable(list2)
                                      .SplitError(it => string.IsNullOrEmpty(it.Item.Name), "名稱不能為空")
                                      .SplitError(it => it.Item.Create<DateTime.Now.AddYears(-1),"不是今年的資料")
                                      .SplitUpdate(it => it.Any(y=>y.Id==it.Item.Id))//存在更新
                                      .SplitInsert(it => true)//剩餘的插入
                                      .ToStorage();
Console.WriteLine(" 插入 {0}  更新{1}  錯誤資料{2} 不計算資料{3}  刪除資料{4},總共{5}" ,
                   x.InsertList.Count,
                   x.UpdateList.Count,
                   x.ErrorList.Count,
                   x.IgnoreList.Count,
                   x.DeleteList.Count,
                   x.TotalList.Count
                ); 

執行程式碼輸出結果:

 

我們可以看到其中有1條可以插入的,1條可以更新的,並且2條錯誤資料

輸出錯誤明細:

foreach (var item in x.ErrorList)
{
        Console.WriteLine("id等於"+item.Item.Id+" : "+item.StorageMessage);
}

  

我們可以看到輸出id3和id4是錯誤的,並且可以輸出具體的錯誤明細

執行更新和插入

x.AsInsertable.ExecuteCommand();
x.AsUpdateable.ExecuteCommand();

 

三、使用表過濾器

SqlSugar以前也支援了全域性過濾器,不過不好用,大部分使用者習慣了以表的方式實現過濾器,用法如下

1、建立表過濾器

 SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { DbType = DbType.SqlServer, ConnectionString = Config.ConnectionString, IsAutoCloseConnection = true });
 db.QueryFilter.Add(new TableFilterItem<Order>(it => it.Name.Contains("a")));  //只有表Order才會生效

2、生效的查詢語句

使用了表過濾器後只要帶有order表的查詢語句,都會自動新增一個條件

 db.Queryable<Order>().ToList();
            //SELECT [Id],[Name],[Price],[CreateTime],[CustomId] FROM [Order]  WHERE  ([Name] like '%'+@MethodConst0+'%') 

 db.Queryable<OrderItem, Order>((i, o) => i.OrderId == o.Id)
                .Where(i => i.OrderId != 0)
                .Select("i.*").ToList();
            //SELECT i.* FROM [OrderDetail] i  ,[Order]  o  WHERE ( [i].[OrderId] = [o].[Id] )  AND ( [i].[OrderId] <> @OrderId0 )  AND  ([o].[Name] like '%'+@MethodConst1+'%')

3、禁止全域性過濾器

db.Queryable<Order>().Filter(null, false).ToList();
 //SELECT [Id],[Name],[Price],[CreateTime],[CustomId] FROM [Order]

  

四、一對多查詢支援條件過濾 

 sqlsugar對於導航查詢也是支援的越來越好,下面是一對多查詢後在過濾的例子

var list7= Db.Queryable<Order>()
.Mapper(it => it.Items, it => it.Items.First().OrderId)
.Where(it => it.Items.Any(y => y.ItemId == 1)) //以前只支援.any()
.ToList();  

 

五、總結

SqlSugar所有功能都真實來自於客戶,並且是多個客戶共同的需求,其實我並沒有做到什麼創新,只是在客戶的基礎上把他們想要的功能進行了一些設計,如果他們用了不滿意,我在這個基礎上在

慢慢的修改

 

原始碼下載:

https://github.com/donet5/SqlSugar   sqlsugar已經持續更新6年之久,也越來越完善 ,如果說EF或者完它ORM不更新了,那麼多一個開源就是多一個選擇

相關文章