用了Dapper之后通篇还是SqlConnection,真的看不下去了

使用 Dapper 进行ASP.NET Core Web API 开发实践 Dapper相对来说,操作比较简单,容易上手,只需要引用一个库文件,而且对多种数据库支持都比较友好,如果希望更简单,还可以下载Dapper的扩展方法Dapper.SimpleCRUD进行更简洁的操作,到这里,你是否有一种跃跃欲试的感觉,赶紧行动起来吧! 阅读详情

一:背景

1. 讲故事

前几天看公司一个新项目的底层使用了dapper,大家都知道dapper是一个非常强大的半自动化orm,帮程序员解决了繁琐的mapping问题,用起来非常爽,但我还是遇到了一件非常不爽的事情,如下代码所示:

    public classUserDAL : BaseDAL
    {
        public List<UserModel> GetList()
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var list = conn.Query<UserModel>("select * from users").ToList();

                return list;
            }
        }

        publicboolInsert()
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var execnum = conn.Execute("insert into xxx ");

                return execnum > 0;

            }
        }

        publicboolUpdate()
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var execnum = conn.Execute("update xxx ....");

                return execnum > 0;
            }
        }
    }

    public classUserModel {}

扫一下代码是不是总感觉哪里不对劲,是的,为了能使用上Dapper的扩展方法,这里面每个方法中都配上了模板化的 using (SqlConnection conn = new SqlConnection(ConnectionString)),虽然这样写逻辑上没有任何问题,但我有洁癖哈,接下来试着封装一下,嘿嘿,用更少的代码做更多的事情。

二:模板化代码封装探索

1. 将模板化的代码提取到父类中

仔细看上面的模板代码你会发现,真正的业务逻辑是写在 using 中的,而该块中只需要拿到一个 conn 就可以了,其他的统一提取封装到父类中,这就可以用到 委托函数啦,对不对,用这个思路代码修改如下:

    public classBaseDAL
    {
        protected string ConnectionString { get; set; }

        public T Execute<T>(Func<SqlConnection, T> func)
        {
            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {
                return func(connection);
            }
        }
    }

有了父类通用的 Execute 方法,接下来子类中就可以直接用它啦,改造如下:

  public classUserDAL : BaseDAL
    {
        public List<UserModel> GetList()
        {
            return Execute((conn) =>
            {
                var list = conn.Query<UserModel>("select * from users").ToList();
                return list;
            });
        }

        public bool Insert()
        {
            return Execute((conn) =>
            {
                var execnum = conn.Execute("insert into xxx ");
                return execnum > 0;
            });
        }

        public bool Update()
        {
            return Execute((conn) =>
            {
                var execnum = conn.Execute("update xxx ....");
                return execnum > 0;
            });
        }
    }

改造之后代码是不是清晰多了,仅仅这一个通用方法貌似还不行,起码 ConnectionString 不能框死。

2. 增加ConnectionString 入口参数

相信有不少朋友的公司是做 ToB 的业务,一般是一个商家一个DB的设计思路,这里就需要在 Execute 上增加一个 ConnectionString 字符串参数,你可以通过重载方法 或者 可选参数,改造如下:

        public T Execute<T>(Func<SqlConnection, T> func)
        {
            return Execute(ConnectionString, func);
        }

        public T Execute<T>(string connectionString, Func<SqlConnection, T> func)
        {
            using (SqlConnection connection = new SqlConnection(connectionString ?? ConnectionString))
            {
                return func(connection);
            }
        }


        public classUserDAL : BaseDAL
        {
            public List<UserModel> GetList(string connectionString)
            {
                return Execute(connectionString, (conn) =>
                {
                    var list = conn.Query<UserModel>("select * from users").ToList();
                    return list;
                });
            }
        }

这样看起来就舒服多了,不过还有一个问题,我们的程序是给客户独立部署的,越简单越好,否则实施人员会砍人的,所以很多用户操作和api轨迹行为都记录到了sqlserver中,这里就有一个 业务表 和 一个 事务日志表,而且要作为原子化提交,这里就涉及到了事务操作。

2. 支持事务操作

因为有同时插入两张表的业务逻辑,免不了使用 transaction,接下来继续扩展 Execute 方法,代码如下:

       public T Execute<T>(Func<SqlConnection, SqlTransaction, T> func)
        {
            return Execute(ConnectionString, func);
        }

        public T Execute<T>(string connectionString, Func<SqlConnection, SqlTransaction, T> func)
        {
            using (SqlConnection connection = new SqlConnection(connectionString ?? ConnectionString))
            {
                connection.Open();
                using (var transaction = connection.BeginTransaction())
                {
                    return func(connection, transaction);
                }
            }
        }

上面的代码应该很好理解,将 transaction 作为回调函数的参数,业务逻辑部分直接将 transaction 塞入到各自的业务代码中即可,子类可以改造如下:

        public bool Insert()
        {
            return Execute((conn, trans) =>
            {
                var execnum = conn.Execute("insert into xxx ", transaction: trans);
                if (execnum == 0) return false;

                var execnum2 = conn.Execute("update xxx set xxx", transaction: trans);
                if (execnum2 > 0) trans.Commit();

                return execnum > 0;
            });
        }

这样 Execute 对 transaction 的支持貌似也差不多了,异步版的我就不在此封装啦。

四:总结

文章来源于工作中的点点滴滴,这也是我的即兴封装,大家要是有更好的封装代码,欢迎交流,独乐乐不如众乐乐,本篇就说到这里啦,希望对您有帮助。

C#中Dapper的使用教程 如果你在小的项目中,使用Entity Framework、NHibernate 来处理大数据访问及关系映射,未免有点杀鸡用牛刀。你又觉得ORM省时省力,这时Dapper 将是你不二的选择。Dapper是一款轻量级ORM工具(Github),Dapper语法十分简单。并且无须迁就数据库的设计,今天通过本文给大家介绍C# Dapper的使用,感兴趣的朋友一起看看吧。Dapper是一款轻量级ORM工具( 阅读详情

相关推荐

基于Dapper的数据访问层

本框架在Dapper的基础上再做封装,支持Lambda表达式树查询也支持纯Sql查询,相对来说比较灵活.实现单个实体的增删改查,可执行存储过程,可输出返回参数,查询结果集可根据实际情况返回DataTable、DataSet和强类型,同时支持不同类型数据库

dapper封装_用了Dapper之后通篇还是SqlConnection,真的看不下去了

一:背景1. 讲故事前几天看公司一个新项目的底层使用了dapper,大家都知道dapper是一个非常强大的半自动化orm,帮程序员解决了繁琐的mapping问题,用起来非常爽,但我还是遇到了一件非常不爽的事情,如下代码所示: public classUserDAL : BaseDAL { public List GetList() { ...

weixin_29915703的博客 400

c#使用dapper连接SQL数据库

使用dapper对数据库进行操作,使对数据库的增删改查变得非常简单,且将数据库配置文件放在外面,可以灵活地更换数据库连接地址

.NET Core Dapper(ORM) 执行sql语句和事物(Transaction)

Dapper 是一个简单的.NET ORM(对象关系映射器)工具,它提供了轻量级的方法来处理数据库操作。与其他ORM工具相比,Dapper的目标是提供快速、简单且非侵入式的数据库访问。Action是.Net中的委托,在委托方法中执行Dapper的具体操作,并且使用传入的连接和事物。

weixin_42098295的博客 1748

dapper:自动SQL制作dapper扩展

精致的 自动SQL制作dapper扩展

从零开始用QP框架开发STM32:事件驱动编程实战指南(附状态机设计技巧)

本文详细介绍了如何使用QP框架在STM32上实现事件驱动编程,包括状态机设计技巧和嵌入式开发实践。通过对比传统前后台系统和RTOS,展示了QP框架在资源占用、实时性和代码可维护性方面的优势,并提供了从环境搭建到高级状态机设计的完整指南。

h6i7j8的博客 1173

Dapper 框架

/// Dapper 框架应用例子 /// 1. NuGet安装 Dapper /// 2. using 就可以使用下面例子 string sql = "SELECT SNAME,SUSER,SDATE,SFLAG,SNUM,CST1,CST2 FROM IIDB_SYN"; str...

weixin_30418341的博客 1285

【IPAM】Netbox docker模式版本升级

NETBOX 是一个开源的网络资源管理系统,主要用于管理 IP 地址、机架、设备、接口等网络资源信息。下面是 NETBOX 的功能、优点和缺点的详细介绍。

u012153104的博客 1330

MicroOrm.Dapper.Repositories vs 原生Dapper:为什么这个ORM库能让你少写80%的SQL?

MicroOrm.Dapper.Repositories是一个基于Dapper的轻量级ORM库,它通过提供强大的CRUD操作封装,帮助开发者减少高达80%的重复SQL编写工作。对于新手和普通用户来说,这个库能够让数据库操作变得更加简单、高效,同时保持原生Dapper的性能优势。 ## 核心优势:告别手写SQL的烦恼 🚀 使用原生Dapper时,开发者需要手动编写大量SQL语句,不仅繁琐易错,

gitblog_00554的博客 611

Cortex-M异常处理深度解析:从HardFault到调试实战

在嵌入式开发中,Cortex-M系列处理器的异常处理机制是保障系统可靠性的核心。然而,面对HardFault、MemManage、BusFault等异常时,开发者往往陷入迷茫。本文结合SEGGER AN00016和Keil AN209两篇权威文档,深入剖析异常根源、寄存器解析及调试技巧,并通过代码实例演示如何快速定位问题。

汽车电子软件领域知识分享 2534

别再只用相机标定了!手把手教你用OpenCV和Python搞定投影仪标定(附完整代码)

本文详细介绍了如何使用Python和OpenCV实现投影仪标定,特别针对结构光三维扫描中的核心问题。通过低成本替代方案和优化算法,解决投影仪标定中的非线性畸变和亮度-距离耦合效应,显著提升三维重建精度。附完整代码和实战技巧,帮助开发者快速掌握关键技术。

weixin_29274337的博客 543
上一篇: 老板:再用Log4j就收拾东西回家吧!
下一篇: 应届毕业生面试第一句话:工资不到一万免谈,HR:我当时就懵了
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值