c# entity freamwork 插入批量数据如何提升性能

在C#中使用Entity Framework(EF)Core进行批量插入数据时,为了提升性能,可以采用以下几种策略:

  1. 批处理操作: EF Core默认情况下并不会一次性执行所有插入操作,而是将它们分批发送给数据库。不过,你可以通过配置DbContext实例的BatchSize属性来显式指定批处理大小。例如,在OnConfiguring方法或DbContext构造函数中设置:

    optionsBuilder.UseSqlServer(
        connectionString,
        x => x.EnableRetryOnFailure()
               .ConfigureCommandTimeout(30)
               .UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery)
               .UseBulkExecution(true) // 从EF Core 6开始支持
               .SetMaxBatchSize(100)); // 自定义批处理大小
    

    注意:UseBulkExecutionSetMaxBatchSize是EF Core 6引入的新特性。

  2. AddRange与SaveChangesAsync: 可以先将多个实体添加到dbContext对象的DbSet ** 中,然后一次性调用SaveChangesAsync方法:

    using (var context = new MyDbContext())
    {
        var entitiesList = new List<MyEntity>();
        // 填充entitiesList...
    
        context.MyEntities.AddRange(entitiesList);
        await context.SaveChangesAsync();
    }
    

    这样做的好处是,EF会尽量合并SQL INSERT语句,减少数据库往返次数。

  3. SqlBulkCopy: 对于非常大的批量插入,EF Core本身并不直接提供类似于数据库内置的BULK INSERT功能。但是,你可以手动创建DataTable或使用内存中的IQueryable结果,然后利用System.Data.SqlClient命名空间下的SqlBulkCopy类进行高效的大规模插入:

    using (var context = new MyDbContext())
    {
        var dataTable = new DataTable();
        // 构建dataTable结构并填充数据...
    
        using (var connection = context.Database.GetDbConnection())
        {
            connection.Open();
    
            using (var bulkCopy = new SqlBulkCopy(connection))
            {
                bulkCopy.DestinationTableName = "MyTable";
                bulkCopy.WriteToServer(dataTable);
            }
        }
    }
    

  4. 第三方库: 若需更高级别的批量插入功能,可考虑使用第三方扩展库如Entity Framework Extensions,它提供了对批量插入、更新等操作的优化支持。

  5. 事务管理: 在处理批量插入时确保在一个事务内完成所有操作,避免每次插入都开启新的事务:

    using (var context = new MyDbContext())
    using (var transaction = context.Database.BeginTransaction())
    {
        try
        {
            foreach (var batch in entitiesList.Batch(1000)) // 假设有一个扩展方法 Batch() 将列表切分成子列表
            {
                context.MyEntities.AddRange(batch);
                context.SaveChanges();
            }
    
            transaction.Commit();
        }
        catch
        {
            transaction.Rollback();
            throw;
        }
    }
    

    请根据实际情况选择适合的方法,并注意权衡批量插入时可能带来的内存消耗和数据库连接资源占用问题。同时,请密切关注EF Core版本特性,因为随着框架的发展,可能会有更多原生支持高性能批量插入的功能。

  • 22
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值