zoukankan      html  css  js  c++  java
  • 轻量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没侵入性,仅通过简单的几个特性,就能让类与数据库关联起来;

    *本系列以静态工厂为例;

    *数据来源于Northwind数据库;

    *完整的代码见   SqlRepoEx2.2.1 GitHub示例  SqlRepoEx2.2.1 码云示例

    一、IDbConnection

    可通过下列两种方式获取

    1、工厂获取

    private static IDbConnection dbConnection = MsSqlRepoFactory.DbConnection;

     

    2、数据仓储

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

    IDbConnection dbConnection = repository.DbConnection;

     

    二、 SQL语句中 @ 参数的生成和定义

     

    1、SqlRepoEx的Insert、Updata 增加了ParamSql()方法获取  @ 参数 语句;

     

    2、对于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} {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

     

    四、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} {item.ProductName2} {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

     

    五、条件查询

     

            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} {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

     

     

    六、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} {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

     

    七、增加(使用实例)

    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} {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

    八、批增加(使用选择)

    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();

     

    九、更新

            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));

     

    十、删除

            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));

     

    十一、使用事务

    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));

     

     

     

  • 相关阅读:
    单链表
    白话经典算法系列之中的一个 冒泡排序的三种实现
    QoS令牌桶工作原理
    BackTrack5 (BT5)无线password破解教程之WPA/WPA2-PSK型无线password破解
    [Django] Base class in the model layer
    MATLAB中导入数据:importdata函数
    联想A798T刷机包 基于百度云V6 集成RE3.1.7美化版 精简冗余文件
    改动symbol link的owner
    利用HttpOnly来防御xss攻击
    【NOIP2014 普及组】螺旋矩阵
  • 原文地址:https://www.cnblogs.com/athinker/p/9829140.html
Copyright © 2011-2022 走看看