/// <summary> /// 批量插入助手 /// </summary> public static class BulkHelper { /// <summary> /// 批量导入入口 /// </summary> /// <param name="con">DbConnection 数据库连接资源</param> /// <param name="models">实体列表</param> /// <param name="tableName">表名</param> /// <typeparam name="T">实体泛型</typeparam> public static void BulkCopy<T>(DbConnection con, List<T> models, string tableName = null) { BulkInsert(con, models, tableName); } /// <summary> /// IList 的扩展方法 用于集合转换 DataTable 类 /// </summary> /// <param name="models">实体列表</param> /// <param name="tableName">表名</param> /// <typeparam name="T">实体泛型</typeparam> /// <returns>DataTable</returns> private static DataTable ToSqlBulkCopyDataTable<T>(this List<T> models, string tableName = null) { var props = TypeDescriptor.GetProperties(typeof(T)); var table = new DataTable { TableName = tableName?.ToLowerInvariant() ?? typeof(T).Name.ToLowerInvariant() }; // 表中 字段(列)的填充 foreach (PropertyDescriptor prop in props) { var type = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType; if (type.IsEnum) type = typeof(int); table.Columns.Add(prop.Name.ToLowerInvariant(), type); } // 表中 数据内容的填充 foreach (var data in models) { var newRow = table.NewRow(); foreach (PropertyDescriptor prop in props) { newRow[prop.Name.ToLowerInvariant()] = prop.GetValue(data) ?? DBNull.Value; } table.Rows.Add(newRow); } return table; } /// <summary> /// 批量导入或修改 /// </summary> /// <param name="con">DbConnection 数据库资源</param> /// <param name="datas">实体列表</param> /// <param name="tableName">表名</param> /// <typeparam name="T">实体泛型</typeparam> private static void BulkInsert<T>(DbConnection con, List<T> datas, string tableName) { // 数据模型列表转换 DataTable var tb = datas.ToSqlBulkCopyDataTable(tableName); var ops = new BulkOperation(con); // 批量插入 引用 Z.BulkOperations ops.BulkInsert(tb); } }
不知性能上和 EF Core 比会不会好一些 gist 地址-> https://gist.github.com/KomiSans/9824c2352f5efdee68bc70bd6917616a
1 INCerry 2022-08-10 18:46:18 +08:00 看了下 反射的那块效率会有点低 其它地方都没啥问题 |
![]() | 2 PendingOni OP @INCerry 有可能的 不过暂时想不到除了用遍历模型列表进行反射添加 Row 到 DataTable 之外更好的方法 |
3 Bazingal 2022-08-10 19:40:41 +08:00 @PendingOni 用 source generators 和多态,编译期生成各个 model 的 ToSqlBulkCopyDataTable 方法 |
![]() | 4 PendingOni OP @Bazingal 感谢指导 我去研究下 |
5 Bazingal 2022-08-10 20:28:56 +08:00 @PendingOni 上面有一点说错了,你的 3 个泛型方法都要生成 |
6 wdwwtzy 2022-08-10 21:01:40 +08:00 ![]() @PendingOni emit 呢? |
![]() | 7 PendingOni OP @wdwwtzy emit? 这个反射的方法暂时还没有试过 我去查下相关文档 |