.NET Dapper mysql 批量新增修改

这篇具有很好参考价值的文章主要介绍了.NET Dapper mysql 批量新增修改。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

dapper是C#程序员比较喜欢用的轻量级ORM,简单易学,只是没有批量新增以及修改(收费版有),写了如下扩展
    /// <summary>
    /// dapper MySQL批量新增修改扩展
    /// </summary>
    public static class DapperExtensions
    {
        /// <summary>
        /// 批量插入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="connection"></param>
        /// <param name="tableName">表名</param>
        /// <param name="items">数据列表</param>
        /// <param name="dataFunc"></param>
        /// <param name="duplicateData">主键相同修改字段</param>
        /// <param name="dbTransaction">事务</param>
        /// <param name="insert">insert,replace,insert ignore</param>
        /// <returns></returns>
        public static async Task BulkInsert<T>(
            this IDbConnection connection,
            string tableName,
            IReadOnlyCollection<T> items,
            Dictionary<string, Func<T, object>> dataFunc, IEnumerable<string>? duplicateData = null, IDbTransaction? dbTransaction = null, string insert = "INSERT")
        {
            const int MaxBatchSize = 5000;
            const int MaxParameterSize = 10000;

            var batchSize = Math.Min((int)Math.Ceiling((double)MaxParameterSize / dataFunc.Keys.Count), MaxBatchSize);
            var numberOfBatches = (int)Math.Ceiling((double)items.Count / batchSize);
            var columnNames = dataFunc.Keys;
            var insertSql = $"{insert} INTO {tableName} ({string.Join(",", columnNames.Select(e => $"`{e}`"))}) VALUES";
            var sqlToExecute = new List<Tuple<string, DynamicParameters>>();

            for (var i = 0; i < numberOfBatches; i++)
            {
                var dataToInsert = items.Skip(i * batchSize)
                    .Take(batchSize);
                var valueSql = GetQueries(dataToInsert, dataFunc);

                sqlToExecute.Add(Tuple.Create($"{insertSql}{string.Join(",", valueSql.Item1)}", valueSql.Item2));
            }

            var duplicate = string.Empty;
            if (duplicateData != null)
            {
                duplicate = $" ON DUPLICATE KEY UPDATE {string.Join(',', duplicateData.Select(d => $"`{d}`=VALUES(`{d}`)"))}";
            }

            foreach (var sql in sqlToExecute)
            {
                await connection.ExecuteAsync(sql.Item1 + duplicate, sql.Item2, commandTimeout: int.MaxValue, transaction: dbTransaction);
            }
        }

        private static Tuple<IEnumerable<string>, DynamicParameters> GetQueries<T>(
            IEnumerable<T> dataToInsert,
            Dictionary<string, Func<T, object>> dataFunc)
        {
            var parameters = new DynamicParameters();

            return Tuple.Create(
                dataToInsert.Select(e => $"({string.Join(",", GenerateQueryAndParameters(e, parameters, dataFunc))})"),
                parameters);
        }

        private static IEnumerable<string> GenerateQueryAndParameters<T>(
            T entity,
            DynamicParameters parameters,
            Dictionary<string, Func<T, object>> dataFunc)
        {
            var paramTemplateFunc = new Func<Guid, string>(guid => $"@p{guid:N}");
            var paramList = new List<string>();

            foreach (var key in dataFunc)
            {
                var paramName = paramTemplateFunc(Guid.NewGuid());
                parameters.Add(paramName, key.Value(entity));
                paramList.Add(paramName);
            }

            return paramList;
        }

        /// <summary>
        /// 批量更新
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="connection"></param>
        /// <param name="tableName">表名</param>
        /// <param name="items">数据列表</param>
        /// <param name="dataFunc"></param>
        /// <param name="primaryFunc"></param>
        /// <param name="primaryKey">主键字段</param>
        /// <param name="isIntKey">主键是否是数字类型</param>
        /// <param name="dbTransaction">事务</param>
        /// <returns></returns>
        public static async Task BulkUpdate<T>(
            this IDbConnection connection,
            string tableName,
            IReadOnlyCollection<T> items,
            Dictionary<string, Func<T, object>> dataFunc, Func<T, object> primaryFunc, string primaryKey, bool isIntKey = true, IDbTransaction? dbTransaction = null)
        {
            const int MaxBatchSize = 5000;
            const int MaxParameterSize = 10000;

            var batchSize = Math.Min((int)Math.Ceiling((double)MaxParameterSize / dataFunc.Keys.Count), MaxBatchSize);
            var numberOfBatches = (int)Math.Ceiling((double)items.Count / batchSize);
            var columnNames = dataFunc.Keys;
            var updateSql = $"UPDATE {tableName} SET";
            var sqlToExecute = new List<Tuple<string, DynamicParameters>>();

            for (var i = 0; i < numberOfBatches; i++)
            {
                var dataToUpdate = items.Skip(i * batchSize)
                    .Take(batchSize);
                var valueSql = GetUpdateQueries(dataToUpdate, dataFunc, primaryFunc, primaryKey, isIntKey);

                sqlToExecute.Add(Tuple.Create($"{updateSql}{valueSql.Item1}", valueSql.Item2));
            }


            foreach (var sql in sqlToExecute)
            {
                await connection.ExecuteAsync(sql.Item1, sql.Item2, commandTimeout: int.MaxValue, transaction: dbTransaction);
            }
        }
        private static Tuple<string, DynamicParameters> GetUpdateQueries<T>(
            IEnumerable<T> dataToUpdate,
            Dictionary<string, Func<T, object>> dataFunc, Func<T, object> primaryFunc, string primaryKey, bool isIntKey)
        {
            var paramTemplateFunc = new Func<Guid, T, (string param, string sql)>((guid, entity) =>
            {
                var keyValue = primaryFunc(entity);
                if (!isIntKey)
                {
                    keyValue = $"'{keyValue}'";
                }
                var param = $"@p{guid:N}";
                var sql = $"WHEN {keyValue} THEN {param}";

                return (param, sql);
            }
            );
            var parameters = new DynamicParameters();
            List<string> sqlList = new();
            foreach (var key in dataFunc)
            {
                var paramList = new List<string>();
                foreach (var e in dataToUpdate)
                {
                    var (param, sql) = paramTemplateFunc(Guid.NewGuid(), e);
                    parameters.Add(param, key.Value(e));
                    paramList.Add(sql);
                }
                sqlList.Add($"`{key.Key}`=CASE `{primaryKey}` {string.Join(" ", paramList)} END");
            }
            object idFunc(T p)
            {
                return primaryFunc(p);
            }
            parameters.Add("@ids", dataToUpdate.Select(idFunc));
            return Tuple.Create(
                $"{string.Join(",", sqlList)} WHERE `{primaryKey}` IN @ids",
                parameters);
        }
    }

 

使用方法:
新增:
 await conn.BulkInsert(
                    "userInfo",    //表名    
                     userinfoList,    //列表
                     new Dictionary<string, Func<UserInfo, object>>
                         {
                             {"Name", u => u.Name },
                             {"Age", u => u.Age },
                             {"Sex", u => u.Sex },
                         });

 文章来源地址https://www.toymoban.com/news/detail-677579.html

修改:
await conn.BulkUpdate("userInfo", userInfoList, new Dictionary<string, Func<UserInfo, object>>
                        {
                           {"Name", u => u.Name }
                             {"Age", u => u.Age },
                             {"Sex", u => u.Sex },
                          }, new Func<UserInfo, object>(u => u.ID), "ID");

到了这里,关于.NET Dapper mysql 批量新增修改的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Dapper.Lite 使用教程

    以MySQL数据库为例 NuGet搜索Dapper.Lite并安装最新版本。 NuGet搜索MySqlConnector并安装最新版本。 也可以使用MySql.Data库,但MySqlConnector库性能更好。 README.md (gitee) wiki (gitee) README.md (github) wiki (github) Dapper.Lite 如有问题加QQ群:497956447。 https://gitee.com/s0611163/Dapper.Lite https://github.com/06

    2024年02月07日
    浏览(34)
  • C#调用Dapper

    Dapper是一种微型ORM(对象关系映射器)工具,可以帮助.NET开发人员轻松地处理数据库操作。它适用于许多数据库提供程序,包括SQL Server、MySQL、Oracle和PostgreSQL等。以下是Dapper的使用介绍: 安装Dapper NuGet包:在Visual Studio解决方案中,右键单击项目名称,选择“管理NuGet程序包

    2024年02月09日
    浏览(34)
  • Dapper-OracleSQLHelper 通用封装

    /// summary     /// Oracle Help 封装使用     /// /summary     /// typeparam name=\\\"T\\\"/typeparam     public class OracleSQLDapperHelperT where T : class     {         /// summary         /// 数据库连接字符串         /// /summary       /*  private static readonly string connectionString =         ConfigurationManager.Co

    2024年01月18日
    浏览(44)
  • Dapper使用自定义表类型的参数

    Dapper1.26及以上版本可以使用自定义类型的表值参数,方便将DataTable类型直接作为一个参数传递到数据库服务器上。 首先在数据库中创建用户自定义,例如: 然后在代码中调用,传统的方式是设置Command的Parameter,设置相应的参数类型: 使用Dapper可以有两种方式传递参数,第

    2024年02月16日
    浏览(32)
  • 以SQLserver为例的Dapper详细讲解

    Dapper是一种轻量级的ORM(对象关系映射)工具,它提供了高效且易于使用的方式来执行数据库操作。 Dapper是由Stack Overflow团队开发并维护的,它的主要目标是提供比EF更快、更直接的方式访问数据库。 Dapper的主要特点包括: 基于纯ADO.NET而不是EF,因此性能更高 支持多种数据

    2023年04月24日
    浏览(44)
  • C#实战:Dapper操作PostgreSQL笔记

    目录 一、PostgreSQL简介 二、PostgreSQL组成 三、PostgreSQL的主要优点 四、PostgreSQL的使用场景 五、示例 1、安装dapper,目前本案例安装的版本是1.50.2 2、安装PostgreSQL驱动 3、数据库链接示例 4、通过SQL查询数据列表写法 5、插入示例写法 PostgreSQL,是一款开源的物理数据库管理系统(

    2024年02月08日
    浏览(35)
  • C# Dapper 操作Oracle数据库

    nuget安装内容   1.配置连接字符串 OracleConnectionString这个可用  2.读取配置文件类 3.Dapper数据库操作类  4.操作数据实例 

    2024年02月10日
    浏览(47)
  • Dapper 操作 PostgreSQL 数据库完全指南

    Dapper 是一个高性能的 ORM 框架,可用于简化与数据库的交互。本文将详细介绍如何使用 Dapper 操作 PostgreSQL 数据库,包括连接配置、CRUD 操作以及示例代码。 首先,确保你的项目中已经添加了 Dapper 和 Npgsql 包。你可以使用以下命令进行安装: 在 appsettings.json 中添加 PostgreSQL

    2024年02月11日
    浏览(62)
  • Java语言创建包含以上数据类型的MySQL表,并提供批量新增数据、批量修改数据、删除数据以及字段的DDL语句的详细代码示例

    以下是使用Java语言创建包含以上数据类型的MySQL表,并提供批量新增数据、批量修改数据、删除数据以及字段的DDL语句的详细代码示例: 请注意,上述代码中的DB_URL、USER和PASS需要根据实际情况进行修改,以连接到正确的MySQL数据库。另外,需要确保已经导入了适当的JDBC驱动

    2024年02月15日
    浏览(75)
  • 执行SQL语句&存储过程的真正【神器】,不用ORM的全选它,比dapper好

    支持.Net Core(2.0及以上)与.Net Framework(4.0及以上)(注意:升级了,可以覆盖到早期的.Net Framework4.0了,而且修复了数据库字段为Null时报错的问题,无敌了!!) 此工具在IDataAccess接口中提供。 已被.Net圈内多家大厂采用! IDataAccess所在的命名空间是:DeveloperSharp.Framework.QueryEngine(

    2024年02月08日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包