SqlServer使用SqlBulkCopy批量插入/更新数据

#region 自己扩展的方法

        ///
        /// 批量插入数据
        ///

        ///
        ///
        public void BatchInsert(List list)
        {
            if (list.Any())
            {
                var pdco = PocoData.ForType(list.FirstOrDefault().GetType(), _defaultMapper);
                string tableName = pdco.TableInfo.TableName;
                using (SqlConnection conn = new SqlConnection(_connectionString))
                {
                    try
                    {
                        conn.Open();
                        //创建属性的集合    
                        List pList = new List();
                        //获得反射的入口    
                        Type type = typeof(T);
                        DataTable dt = new DataTable();
                        dt = ConvertToDataTable(list);
                        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn))
                        {
                            bulkCopy.DestinationTableName = tableName;
                            bulkCopy.BatchSize = list.Count;
                            if (dt != null && dt.Rows.Count != 0)
                            {
                                bulkCopy.WriteToServer(dt);
                            }
                            bulkCopy.Close();
                        }
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }
        }

        ///
        /// 批量更新数据
        ///

        ///
        ///
        public void BatchUpdate(List list)
        {
            if (list.Any())
            {
                BatchUpdate(list, null, null);
            }
        }

        ///
        /// 批量更新数据
        ///

        ///
        /// 实体集合
        /// 需要更新哪些列,为null是更新所有列
        /// 跟新条件,默认是主键,多个条件关系是并列的and
        public void BatchUpdate(List list, IEnumerable columns, Dictionary onRelations)
        {
            var sbUpdateColumns = new StringBuilder();
            var sbOnRelation = new StringBuilder();
            var pdco = PocoData.ForType(list.FirstOrDefault().GetType(), _defaultMapper);
            var dt = new DataTable();
            var tableName = pdco.TableInfo.TableName;
            var columnsIndex = 0;
            var onRelationIndex = 0;

            //构建需要更新的列
            if (columns == null)
            {
                foreach (var i in pdco.Columns)
                {
                    if (i.Key.ToLower() != pdco.TableInfo.PrimaryKey.ToLower())
                    {
                        // Build the sql
                        if (columnsIndex > 0)
                            sbUpdateColumns.Append(", ");
                        sbUpdateColumns.AppendFormat("T.{0} = Temp.{0}", i.Key);
                        columnsIndex++;
                    }
                }
            }
            else
            {
                foreach (var colname in columns)
                {
                    var pc = pdco.Columns[colname];

                    // Build the sql
                    if (columnsIndex > 0)
                        sbUpdateColumns.Append(", ");
                    sbUpdateColumns.AppendFormat("T.{0} = Temp.{0}", colname);
                    columnsIndex++;
                }
            }

            //构建更新条件
            if (onRelations == null)
            {

                sbOnRelation.AppendFormat("T.{0} = Temp.{1}", pdco.TableInfo.PrimaryKey, pdco.TableInfo.PrimaryKey);
            }
            else
            {
                foreach (var onRelation in onRelations)
                {
                    if (onRelationIndex > 0)
                        sbOnRelation.Append(" AND ");
                    sbOnRelation.AppendFormat("T.{0} = Temp.{1}", onRelation.Key, onRelation.Value);
                    onRelationIndex++;
                }
            }

            using (SqlConnection conn = new SqlConnection(_connectionString))
            {
                using (SqlCommand command = new SqlCommand("", conn))
                {
                    try
                    {
                        conn.Open();
                        var tempTableName = $"Temp{DateTime.Now.ToString("yyyMMddHHmmss")}";

                        //构建临时表
                        command.CommandText = $"SELECT * INTO {tempTableName} FROM {tableName} WHERE 1 = 2;";
                        command.ExecuteNonQuery();

                        //插入临时表
                        dt = ConvertToDataTable(list);
                        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(_connectionString, SqlBulkCopyOptions.KeepIdentity))
                        {
                            bulkCopy.DestinationTableName = tempTableName;
                            bulkCopy.BatchSize = list.Count;
                            if (dt != null && dt.Rows.Count != 0)
                            {
                                bulkCopy.WriteToServer(dt);
                                bulkCopy.Close();
                            }
                        }

                        //从临时表更新到原表,并删除临时表
                        command.CommandTimeout = 300;
                        command.CommandText = $"UPDATE T SET {sbUpdateColumns.ToString()} FROM {_provider.EscapeTableName(tableName)} T INNER JOIN {tempTableName} Temp ON {sbOnRelation.ToString()}; DROP TABLE {tempTableName};";
                        command.ExecuteNonQuery();
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }
        }

        ///
        /// 类集合转为DataTable
        ///

        public static DataTable ConvertToDataTable(IList data)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
            DataTable table = new DataTable();
            foreach (PropertyDescriptor prop in properties)
                table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
            foreach (T item in data)
            {
                DataRow row = table.NewRow();
                foreach (PropertyDescriptor prop in properties)
                    row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
                table.Rows.Add(row);
            }
            return table;
        }

        #endregion

你可能感兴趣的:(C#)