EF批量添加

  1.首先,打开工具——NuGet包管理器——管理解决方案的NoGet程序包——搜索Z.EntityFramework.Extensions

  

  点击安装!!!

  

  codefirst定义一个实体,用EF的方法添加数据

  static void Main(string[] args)
        {
            using (ConsoleDBContext context = new ConsoleDBContext())
            {
                // '''定义要添加数据的条数'''
                int customerCount = 10000;

                //  '''定义一个实体集合'''
                List<Users> customers = new List<Users>();

                var sw = new Stopwatch();
                sw.Start();
                // '''想集合中添加数据'''
                for (int i = 0; i < customerCount; i++)
                {
                    Users customer = new Users()
                    {
                        id = Guid.NewGuid(),
                        name = i + ""
                    };
                    //customers.Add(customer);
                    context.Users.Add(customer);
                }
                context.SaveChanges();
                
                //context.BulkInsert(customers);
                //context.BulkSaveChanges();
                sw.Stop();
                Console.Write(sw.Elapsed);
                Console.ReadKey();
            }

        }

运行完成:插入10000条数据,用时55秒

接下来我们看看用EF的拓展方法能用多长时间

  static void Main(string[] args)
        {
            using (ConsoleDBContext context = new ConsoleDBContext())
            {
                // '''定义要添加数据的条数'''
                int customerCount = 10000;

                //  '''定义一个实体集合'''
                List<Users> customers = new List<Users>();

                var sw = new Stopwatch();
                sw.Start();
                // '''想集合中添加数据'''
                for (int i = 0; i < customerCount; i++)
                {
                    Users customer = new Users()
                    {
                        id = Guid.NewGuid(),
                        name = i + ""
                    };
                    customers.Add(customer);
                    //context.Users.Add(customer);
                }
                //context.SaveChanges();
                context.BulkInsert(customers);
                context.BulkSaveChanges();
                sw.Stop();
                Console.Write(sw.Elapsed);
                Console.ReadKey();
            }
        }

运行完成:插入10000条数据,用时到0.2秒

为什么扩展方法用的时间这么少?

EF自带的方法,会增加与数据库的交互次数,一般地,EF的一个上下文在提交时会打开一个数据连接,然后把转换成的SQL语句一条一条的发到数据库端,然后去提交,下面的图片是我用SQL Server Profiler记录的和数据库交互的操作,这只是一小部分,试想,如果你的数据量达到万级别(更不用说百万,千万数据了),那对数据库的压力是很大的

这里写图片描述

而扩展方法运行时与数据库的交互是这样的:

这里写图片描述

批量添加的方法是生成一条SQL语句,和数据库只交互一次。那为什么图片中有多条Insert语句呢,当你使用BulkInsert时,如果数据达到4万之前,那在SQL的解释时,也是很有压力的,有多情况下会超时,当然这与你的数据库服务器有关,但为了性能与安全,将Bulk操作变为分批提交,即将上W的数据进行分解,分用1W数据量提交一次,这样,对数据库的压力就小一些。

 不过这种方法好像不能进行多表操作(有主外键的),如果有朋友研究好了,可以给我留言 sun645430@163.com

下面的分析引用风枫疯的文章,在这里注明:https://www.cnblogs.com/xuyufeng/p/6612589.html

转载于:https://www.cnblogs.com/mi21/p/9875679.html

<think>好的,我现在需要回答用户关于EF(Entity Framework)批量添加、事务等高级操作的问题。首先,我要确保自己正确理解用户的需求。他们可能在使用Entity Framework进行数据库操作时遇到了性能问题,特别是在处理大量数据时,逐条插入效率低下,或者需要保证多个操作的事务性。用户希望了解如何高效地进行批量添加以及如何使用事务来确保数据的一致性。 接下来,我需要回忆和整理关于EF批量操作和事务的相关知识。对于批量添加,我记得在EF Core中,原生的`AddRange`方法并不是真正的批量操作,它仍然会生成多个INSERT语句,性能可能不够理想。因此,可能需要提到一些第三方库,比如EF Core的扩展库,或者使用原生SQL命令来执行批量插入。 关于事务,EF Core支持使用`DbContext.Database.BeginTransaction()`来显式管理事务,也可以使用`TransactionScope`在分布式事务中使用。需要解释如何将这些事务应用到多个数据库操作中,确保要么全部成功,要么全部回滚。 另外,用户可能对EF Core中的ExecuteDelete和ExecuteUpdate方法不太熟悉,这些方法在最新的版本中支持批量删除和更新,应该提及这些新特性以提高效率。 还需要注意区分不同版本的EF Core,比如某些功能可能在旧版本中不可用,比如ExecuteDelete和ExecuteUpdate是在EF Core 7.0引入的。如果用户使用的是较旧的版本,可能需要建议升级或者使用替代方法。 然后,我需要考虑如何结构清晰地组织这些信息。首先介绍批量添加,包括原生方法和第三方库,然后讨论事务管理,最后提到其他批量操作如删除和更新。同时,要给出示例代码,帮助用户更好地理解如何实现这些操作。 在写作过程中,要确保使用正确的中文术语,避免技术术语的误用。例如,“事务”而非“交易”,“回滚”而不是“撤销”。同时,代码示例需要符合C#和EF Core的语法规范,比如正确使用`using`语句管理事务,正确调用`SaveChangesAsync`等。 还需要检查是否有遗漏的重要点,比如在事务处理中的异常处理,确保在发生异常时回滚事务。此外,提醒用户在使用第三方库时要注意兼容性和维护性,比如EF Core Bulk Extensions可能需要根据项目情况评估是否引入。 最后,总结部分需要简明扼要地回顾主要要点,帮助用户巩固记忆。同时,邀请用户进一步提问,促进交流。 现在需要将这些思考整理成一个结构清晰、分步骤的中文回答,涵盖批量添加、事务管理、其他批量操作,并给出注意事项和示例代码。确保遵循用户提供的系统级指令,特别是关于LaTeX格式的使用,但在这个问题中可能涉及较少,不过要注意数学表达式如果有的话要正确使用$...$格式。</think>以下是关于EF(Entity Framework)批量添加、事务等高级操作的详细介绍: --- ### 一、批量添加操作 在EF中逐条插入数据(如循环调用`Add()`)效率低下,以下为优化方案: #### 1. **原生批量添加(`AddRange`)** - **原理**:将多个实体一次性添加到上下文,但生成多条`INSERT`语句。 - **代码示例**: ```csharp var entities = new List<Entity>(); for (int i = 0; i < 1000; i++) { entities.Add(new Entity { ... }); } context.AddRange(entities); await context.SaveChangesAsync(); // 生成1000条INSERT语句 ``` #### 2. **高性能批量插入(第三方库)** - **推荐库**:`EFCore.BulkExtensions`、`Z.EntityFramework.Extensions`。 - **优势**:生成单条批量插入语句(如`BULK INSERT`),性能提升显著。 - **代码示例**(使用`EFCore.BulkExtensions`): ```csharp await context.BulkInsertAsync(entities); // 单条SQL批量插入 ``` #### 3. **原生SQL批量插入** - **适用场景**:完全控制SQL语句时。 - **示例**: ```csharp var sql = "INSERT INTO Entities (...) VALUES (...), (...), ..."; await context.Database.ExecuteSqlRawAsync(sql); ``` --- ### 二、事务管理 事务用于确保多个操作的原子性(要么全成功,要么全回滚)。 #### 1. **显式事务(推荐)** - **步骤**:创建事务 → 执行操作 → 提交或回滚。 - **代码示例**: ```csharp using (var transaction = context.Database.BeginTransaction()) { try { // 操作1 context.Add(entity1); await context.SaveChangesAsync(); // 操作2 context.Add(entity2); await context.SaveChangesAsync(); transaction.Commit(); // 提交事务 } catch { transaction.Rollback(); // 回滚事务 } } ``` #### 2. **`TransactionScope`(分布式事务)** - **适用场景**:跨多个数据库或服务的操作。 - **代码示例**: ```csharp using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { // 操作1(可能涉及不同数据库) await context1.SaveChangesAsync(); // 操作2 await context2.SaveChangesAsync(); scope.Complete(); // 标记事务完成 } ``` --- ### 三、其他批量操作 #### 1. **批量删除** - **原生方式**:先查询再删除(低效): ```csharp var entities = context.Entities.Where(e => e.IsDeleted); context.RemoveRange(entities); await context.SaveChangesAsync(); // 生成多条DELETE ``` - **高效方式**(EF Core 7.0+): ```csharp await context.Entities .Where(e => e.IsDeleted) .ExecuteDeleteAsync(); // 生成单条DELETE语句 ``` #### 2. **批量更新** - **传统方式**:逐条修改(低效)。 - **高效方式**(EF Core 7.0+): ```csharp await context.Entities .Where(e => e.Date < DateTime.Now) .ExecuteUpdateAsync(setters => setters.SetProperty(e => e.Status, "Expired") ); // 单条UPDATE语句 ``` --- ### 四、注意事项 1. **版本兼容性**:`ExecuteUpdate/Delete`需EF Core 7.0+。 2. **第三方库权衡**:评估项目依赖与维护成本。 3. **事务范围**:避免长时间持有事务导致锁竞争。 4. **异常处理**:务必在`try-catch`中回滚事务。 --- ### 总结 | 操作类型 | 推荐方法 | 性能影响 | |----------------|-----------------------------|---------------| | 批量插入 | `EFCore.BulkExtensions` | 高(单条SQL) | | 事务管理 | 显式事务(`BeginTransaction`) | 可控原子性 | | 批量删除/更新 | `ExecuteDelete/Update` | 高(单条SQL) | 如有具体场景或代码问题,欢迎进一步提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值