欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

轻量ORM-SqlRepoEx (十四)最佳实践之Dapper(1)

程序员文章站 2022-04-15 10:42:03
SqlRepoEx是 .Net平台下兼容.NET Standard 2.0人一个轻型的ORM。解决了Lambda转Sql语句这一难题,SqlRepoEx使用的是Lambda表达式,所以,对c#程序员来说,是非常简单的,其语法特点与Linq to Sql极为相似。不仅实现了完整的Select、Inse... ......

简介: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}\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

 

四、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

 

五、条件查询

 

        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

 

 

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

 

七、增加(使用实例)

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

八、批增加(使用选择)

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