//EF批量添加数据性能慢的问题的解决方案 public ActionResult BatchAdd() { using (var db = new ToneRoad.CEA.DbContext.DbContext()) { //**********************第一种解决方案 直接使用sql********************** string sqls = ""; for (int i = 0; i < 100000; i++) { sqls += "sql" + i; } db.Database.ExecuteSqlCommand(sqls); //**********************第二种解决方案 异步并行计算********************** List<SYS_User> LIST = new List<SYS_User>(); ParallelOptions _po = new ParallelOptions(); _po.MaxDegreeOfParallelism = Environment.ProcessorCount; Parallel.ForEach<SYS_User>(LIST, c => { db.SYS_User.Add(c); db.SaveChanges(); }); //**********************第三种解决方案 关闭EF跟踪验证********************** //关闭 自动跟踪对象的属性变化的功能,默认情况下EF会开启对附加到EF上下文中的实体对象进行校验,看已经附加到上下文中的实体对象的属性是否发生变化,这在大量数据添加时会影响性能。 db.Configuration.AutoDetectChangesEnabled = false; //保存前验证对象的属性最大最小长度等,默认为true,关闭会提高性能 db.Configuration.ValidateOnSaveEnabled = false; List<SYS_User> list = new List<SYS_User>(); for (int i = 0; i < 100000; i++) { SYS_User user = new SYS_User() { UserName = "sa", Password = "123" }; list.Add(user); } db.SYS_User.AddRange(list); db.SaveChanges(); //**********************第四种解决方案 使用SQL Server的bcp命令********************** //Microsoft SQL Server 提供的一个称为 bcp(批量流处理)) 的流行的命令提示符实用工具,用于将数据从一个表移动到另一个表 List<SYS_User> lists = new List<SYS_User>(); for (int i = 0; i < 100000; i++) { SYS_User user = new SYS_User() { UserName = "sa", Password = "123" }; lists.Add(user); } BulkCopy<SYS_User>(db, lists); return View(); } } public void BulkCopy<T>(ToneRoad.CEA.DbContext.DbContext db, IList<T> list) { using (var con = db.Database.Connection as System.Data.SqlClient.SqlConnection) { con.Open(); using (var bulkCopy = new SqlBulkCopy(con)) { bulkCopy.BatchSize = list.Count; bulkCopy.DestinationTableName = typeof(T).Name; var table = new DataTable(); var props = TypeDescriptor.GetProperties(typeof(T)) .Cast<PropertyDescriptor>() .Where(propertyInfo => propertyInfo.PropertyType.Namespace.Equals("System")) .ToArray(); foreach (var propertyInfo in props) { bulkCopy.ColumnMappings.Add(propertyInfo.Name, propertyInfo.Name); table.Columns.Add(propertyInfo.Name, Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType); } var values = new object[props.Length]; foreach (var item in list) { for (var i = 0; i < values.Length; i++) { values[i] = props[i].GetValue(item); } table.Rows.Add(values); } bulkCopy.WriteToServer(table); } con.Close(); } }
时间: 2024-11-10 05:04:59