輕量ORM-SqlRepoEx (十四)最佳實踐之Dapper(1)

簡介:SqlRepoEx是 .Net平臺下兼容.NET Standard 2.0人一個輕型的ORM。解決了Lambda轉Sql語句這一難題,SqlRepoEx使用的是Lambda表達式,因此,對c#程序員來講,是很是簡單的,其語法特色與Linq to Sql極爲類似。不只實現了完整的Select、Insert、Update、Delete等語句解析器,同時,也實現了Select、where、order by等子句,這些語句與子句均支持導出SQL語句,使得拼接複雜場景SQL語句變得輕鬆,SqlRepoEx很快其原生數據訪問與Dapper不相上下,SqlRepoEx自己支持Sql Server與MySql方言,同時經過SqlRepoEx.Normal支持非方言SQL。SqlRepoEx沒侵入性,僅經過簡單的幾個特性,就能讓類與數據庫關聯起來;git

*本系列以靜態工廠爲例;程序員

*數據來源於Northwind數據庫;github

*完整的代碼見   SqlRepoEx2.2.1 GitHub示例  SqlRepoEx2.2.1 碼雲示例數據庫

1、IDbConnection

可經過下列兩種方式獲取c#

一、工廠獲取app

private static IDbConnection dbConnection = MsSqlRepoFactory.DbConnection;ui

 

二、數據倉儲this

var repository = MsSqlRepoFactory.Create<AzProducts>();orm

IDbConnection dbConnection = repository.DbConnection;事務

 

2、 SQL語句中 @ 參數的生成和定義

 

一、SqlRepoEx的Insert、Updata 增長了ParamSql()方法獲取  @ 參數 語句;

 

二、對於Where條件語句中,如要生成  @ 參數 語句 只須要在表達式中 .Where(p => p.ProductID == p.ProductID);右側表達式中使用類型屬性表達式便可。

 

三、關於數據字段與屬性聯,將在下篇中介紹

 

3、 簡單查詢

 

public static void QueryOnly()

{

 // 建立數據倉儲

var repository = MsSqlRepoFactory.Create<AzProducts>();

        //查詢

var result = repository.Query().Top(10);

Console.WriteLine(result.Sql());

// 經過 Dapper 獲取數據

IEnumerable<AzProducts> azProducts = dbConnection.Query<AzProducts>(result.Sql());

// 顯示結果(只取兩列,僅爲顯示目的)

foreach (var item in azProducts)

{

Console.WriteLine($"{item.ProductID}\t{item.ProductName2}");

}

      }

此方法生成的 SQL

SELECT TOP (10) [dbo].[Products].[ProductID]

, [dbo].[Products].[ProductName] as [ProductName2]

, [dbo].[Products].[SupplierID]

, [dbo].[Products].[CategoryID]

, [dbo].[Products].[QuantityPerUnit]

, [dbo].[Products].[UnitPrice]

, [dbo].[Products].[UnitsInStock]

, [dbo].[Products].[UnitsOnOrder]

, [dbo].[Products].[ReorderLevel]

, [dbo].[Products].[Discontinued]

FROM [dbo].[Products];

此方法生成的結果

1       Chai

2       Chang

3       Aniseed Syrup

4       Chef Anton's Cajun Seasoning

5       Chef Anton's Gumbo Mix

6       Grandma's Boysenberry Spread

7       Uncle Bob's Organic Dried Pears

8       Northwoods Cranberry Sauce

9       Mishi Kobe Niku

10      Ikura

 

4、InnerJoin 查詢

* LeftOuterJoin、RightOuterJoin與此例類似

        public static void DoInnerJoin()

        {

 // 建立數據倉儲

var repository = MsSqlRepoFactory.Create<AzProducts>();

// 構建查詢語句,相較而言,語法更接近於SQL,與Linq是有很大區別的

var result = repository.Query()

   .InnerJoin<AzSuppliers>()

   .On<AzSuppliers>((l, r) => l.SupplierID == r.SupplierID, r => r.CompanyName)

   .Top(10);

Console.WriteLine(result.Sql());

Console.WriteLine();

// 經過 Dapper 獲取數據

IEnumerable<AzProducts> azProducts = dbConnection.Query<AzProducts>(result.Sql());

foreach (var item in azProducts)

{

Console.WriteLine($"{item.ProductID}\t{item.ProductName2}\t{item.Supplier}");

}

        }

此方法生成的 SQL

SELECT TOP (10) [dbo].[Products].[ProductID]

, [dbo].[Products].[ProductName] as [ProductName2]

, [dbo].[Products].[SupplierID]

, [dbo].[Products].[CategoryID]

, [dbo].[Products].[QuantityPerUnit]

, [dbo].[Products].[UnitPrice]

, [dbo].[Products].[UnitsInStock]

, [dbo].[Products].[UnitsOnOrder]

, [dbo].[Products].[ReorderLevel]

, [dbo].[Products].[Discontinued]

, [dbo].[Suppliers].[CompanyName] as [Supplier]

FROM [dbo].[Products]

INNER JOIN [dbo].[Suppliers]

ON [dbo].[Products].[SupplierID] = [dbo].[Suppliers].[SupplierID];

此方法生成的結果

1       Chai    Exotic Liquids

2       Chang   Exotic Liquids

3       Aniseed Syrup   Exotic Liquids

4       Chef Anton's Cajun Seasoning    New Orleans Cajun Delights

5       Chef Anton's Gumbo Mix  New Orleans Cajun Delights

6       Grandma's Boysenberry Spread    Grandma Kelly's Homestead

7       Uncle Bob's Organic Dried Pears Grandma Kelly's Homestead

8       Northwoods Cranberry Sauce      Grandma Kelly's Homestead

9       Mishi Kobe Niku Tokyo Traders

10      Ikura   Tokyo Traders

 

5、條件查詢

 

        public static void QueryWhere()

        {

 // 建立數據倉儲

            var repository = MsSqlRepoFactory.Create<AzProducts>();

            var result = repository.Query()

                                    .Where(p => p.ProductName2.Contains("t") && p.ProductID < 100)

                                    .Top(10);

            Console.WriteLine(result.Sql());

            Console.WriteLine();

 // 經過 Dapper 獲取數據

            IEnumerable<AzProducts> azProducts = dbConnection.Query<AzProducts>(result.Sql());

 

            foreach (var item in azProducts)

            {

                Console.WriteLine($"{item.ProductID}\t{item.ProductName2}");

            }

        }

此方法生成的 SQL

SELECT TOP (10) [dbo].[Products].[ProductID]

, [dbo].[Products].[ProductName] as [ProductName2]

, [dbo].[Products].[SupplierID]

, [dbo].[Products].[CategoryID]

, [dbo].[Products].[QuantityPerUnit]

, [dbo].[Products].[UnitPrice]

, [dbo].[Products].[UnitsInStock]

, [dbo].[Products].[UnitsOnOrder]

, [dbo].[Products].[ReorderLevel]

, [dbo].[Products].[Discontinued]

FROM [dbo].[Products]

WHERE ((([dbo].[Products].[ProductName] LIKE '%t%') and ([dbo].[Products].[ProductID] < 100)));

此方法生成的結果

4       Chef Anton's Cajun Seasoning

5       Chef Anton's Gumbo Mix

8       Northwoods Cranberry Sauce

12      Queso Manchego La Pastora

14      Tofu

17      Alice Mutton

18      Carnarvon Tigers

19      Teatime Chocolate Biscuits

22      Gustaf's Kn?ckebr?d

23      Tunnbr?d

 

 

6、Union

      public static void QueryUnion()

        {

// 建立數據倉儲

            var repository = MsSqlRepoFactory.Create<AzCustomers>();

            // 此語句不會參與數據查詢,只是做爲Union的包裹

            // 若是此語句自己也是數據查詢,請增長到new List<UnionSql>中

            var result = repository.Query()

                                   .Select(c => c.CustomerID, c => c.CompanyName);

            var result01 = repository.Query()

                                    .Select(c => c.CustomerID, c => c.CompanyName)

                                    .Where(c => c.CustomerID == "ANATR");

            var result02 = repository.Query()

                                    .Select(c => c.CustomerID, c => c.CompanyName)

                                    .Where(c => c.CustomerID == "FRANK");

            var result03 = repository.Query()

                                    .Select(c => c.CustomerID, c => c.CompanyName)

                                    .Where(c => c.CustomerID == "TRADH");

            var resultAllSql = result.UnionSql(new List<UnionSql>  {

                UnionSql.New(  result01,UnionType.Union ),

                UnionSql.New(  result02,UnionType.Union ),

                UnionSql.New(  result03,UnionType.Union ), });

            Console.WriteLine(resultAllSql);

            Console.WriteLine();

// 經過 Dapper 獲取數據

            IEnumerable<AzCustomers> azCustomers = dbConnection.Query<AzCustomers>(resultAllSql);

            foreach (var item in azCustomers)

            {

                Console.WriteLine($"{item.CustomerID}\t{item.CompanyName}");

            }

        }

此方法生成的 SQL

SELECT [_this_is_union].[CustomerID]

, [_this_is_union].[CompanyName]

FROM ( SELECT [dbo].[Customers].[CustomerID]

, [dbo].[Customers].[CompanyName]

FROM [dbo].[Customers]

WHERE (([dbo].[Customers].[CustomerID] = 'ANATR'))

UNION

 SELECT [dbo].[Customers].[CustomerID]

, [dbo].[Customers].[CompanyName]

FROM [dbo].[Customers]

WHERE (([dbo].[Customers].[CustomerID] = 'FRANK'))

UNION

 SELECT [dbo].[Customers].[CustomerID]

, [dbo].[Customers].[CompanyName]

FROM [dbo].[Customers]

WHERE (([dbo].[Customers].[CustomerID] = 'TRADH')) )

AS  _this_is_union

此方法生成的結果

ANATR   Ana Trujillo Emparedados y helados

FRANK   Frankenversand

TRADH   Tradi??o Hipermercados

 

7、增長(使用實例)

public static void DoInsertEntityParam()

        {

            var repository = MsSqlRepoFactory.Create<AzProducts>();

            AzProducts azProduct = new AzProducts { ProductName2 = "testvalue" };

            var resultinsert = repository

                                    .Insert();

           // 使用ParamSql()方法獲取 @ 參數SQL語句

            Console.WriteLine(resultinsert.ParamSql());

            Console.WriteLine();

 

            // 需返回自增字段,因此用Query

            IEnumerable<AzProducts> azProducts = dbConnection.Query<AzProducts>(resultinsert.ParamSql(), azProduct);

 

            foreach (var item in azProducts)

            {

                Console.WriteLine($"{item.ProductID}\t{item.ProductName2}");

            }

 

        }

此方法生成的 SQL

INSERT [dbo].[Products]([ProductName],[SupplierID],[CategoryID],[QuantityPerUnit],[UnitPrice],[UnitsInStock],[UnitsOnOrder],[ReorderLevel],[Discontinued])

VALUES(@ProductName2,@SupplierID,@CategoryID,@QuantityPerUnit,@UnitPrice,@UnitsInStock,@UnitsOnOrder,@ReorderLevel,@Discontinued);

SELECT [ProductID],[ProductName] as ProductName2,[SupplierID],[CategoryID],[QuantityPerUnit],[UnitPrice],[UnitsInStock],[UnitsOnOrder],[ReorderLevel],[Discontinued]

FROM [dbo].[Products]

WHERE [ProductID] = SCOPE_IDENTITY();

此方法生成的結果

96      testvalue

8、批增長(使用選擇)

public static void DoInsertEntityParamBatch()

        {

            // 建立數據倉儲

            var repository = MsSqlRepoFactory.Create<AzProducts>();

            // 設置要批處理的數據

            List<AzProducts> azProductList = new List<AzProducts>{

              new AzProducts { ProductName2 = "testvalue1" ,CategoryID=1,UnitPrice=123},

              new AzProducts { ProductName2 = "testvalue2" ,CategoryID=1,UnitPrice=123},

              new AzProducts { ProductName2 = "testvalue3" ,CategoryID=1,UnitPrice=123},

              new AzProducts { ProductName2 = "testvalue4" ,CategoryID=1,UnitPrice=123 },

              new AzProducts { ProductName2 = "testvalue5" ,CategoryID=1,UnitPrice=123},

              new AzProducts { ProductName2 = "testvalue6" ,CategoryID=1,UnitPrice=123},

            };

           // 使用選擇增長

            var resultinsert = repository

                                    .Insert().ParamWith(c => c.ProductName2, c => c.UnitPrice, c => c.CategoryID);

 

            Console.WriteLine(resultinsert.ParamSql());

            Console.WriteLine();

 

            // 經過 Dapper 批處理

            dbConnection.Execute(resultinsert.ParamSql(), azProductList);

       }

此方法生成的 SQL

INSERT [dbo].[Products]([ProductName],[UnitPrice],[CategoryID])

VALUES(@ProductName2,@UnitPrice,@CategoryID);

SELECT [ProductName] as ProductName2,[UnitPrice],[CategoryID],[ProductID]

FROM [dbo].[Products]

WHERE [ProductID] = SCOPE_IDENTITY();

 

9、更新

        public static void DoUpdateEntityParam()

        {

           // 建立數據倉儲

            var repository = MsSqlRepoFactory.Create<AzProducts>();

           // 構建更新語句

            var resultUpdate = repository

                                    .Update()

                                    .ParamSet(p => p.ProductName2, p => p.CategoryID)

           // Where 中使用下列格式語句,可生成帶 @ 的參數

                                    .Where(p => p.ProductID == p.ProductID);

            Console.WriteLine(resultUpdate.ParamSql());

            Console.WriteLine();

           // 需更新的數據

            AzProducts products = new AzProducts() { ProductID = 84, ProductName2 = "testvalue100", CategoryID = 7 };

           // 經過 Dapper 更新數據

            int result = dbConnection.Execute(resultUpdate.ParamSql(), products);

           Console.WriteLine($"{result}");

        }

此方法生成的 SQL

UPDATE [dbo].[Products]

SET ProductName  = @ProductName2, CategoryID  = @CategoryID

WHERE (([dbo].[Products].[ProductID] = @ProductID));

 

10、刪除

        public static void DoDeleteEntity(bool go = false)

        {

 // 建立數據倉儲

            var repository = MsSqlRepoFactory.Create<AzProducts>();

           // 要刪除的數據

            AzProducts azProducts = new AzProducts { ProductName2 = "testvalue", ProductID = 81 };

            // 構建刪除,使用實例構建時,若是不設置 Where 語句

           // SqlRepoEx 會以關鍵詞來構建  Where 語句

            var resultUpdate = repository.Delete().For(azProducts);

            Console.WriteLine(resultUpdate.Sql());

            Console.WriteLine();

           // 經過 Dapper 刪除數據

            int result = dbConnection.Execute(resultUpdate.Sql());

            Console.WriteLine($"{result}");

        }

此方法生成的 SQL

DELETE [dbo].[Products]

WHERE (([dbo].[Products].[ProductID] = @ProductID));

 

11、使用事務

public static void DoDeleteTransaction()

        {

           // 建立數據倉儲

            var repository = MsSqlRepoFactory.Create<AzProducts>();

           // 構建刪除,若是不是實例構建,用戶必需自行指定刪除條件

            // Where 中使用下列格式語句,可生成帶 @ 的參數

            var resultUpdate = repository.Delete().Where(p => p.ProductID == p.ProductID);

               // 要刪除的數據集

            List<AzProducts> azProductList = new List<AzProducts>

            {

                new AzProducts{ProductID=92},

                new AzProducts{ProductID=93},

                new AzProducts{ProductID=94},

                new AzProducts{ProductID=91},

            };

            Console.WriteLine(resultUpdate.Sql());

            Console.WriteLine();

            // 使用事務控制

            using (var transaction = dbConnection.BeginTransaction())

            {

           //  經過 Dapper 刪除,同時指定了事務

                dbConnection.Execute(resultUpdate.Sql(), azProductList, transaction: transaction);

           // 僅爲了演示,此處回滾事務,取消刪除

           // 若是相要提交事務,請將此處改成 transaction.Commit() 可看到刪除效果

                transaction.Rollback();

            }

        }

此方法生成的 SQL

DELETE [dbo].[Products]

WHERE (([dbo].[Products].[ProductID] = @ProductID));

相關文章
相關標籤/搜索