/// <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 1
@PendingOni emit 呢?
|
7
PendingOni OP @wdwwtzy emit? 这个反射的方法暂时还没有试过 我去查下相关文档
|