Sql和Mysql 批量提交方法
#region 使用SqlBulkCopy将DataTable中的数据批量插入数据库中 #region MySql批量提交 /// <summary> /// MySql批量提交 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="TbName">表名</param> /// <param name="PrintKey">如果主键不是自增长ID,则可以输入空字符串</param> /// <param name="lstData">需要插入表格内容</param> /// <param name="IsAutoPrintKey">主键是否自增长</param> /// <returns></returns> public int SqlBulkToMySQl<T>(string TbName, string PrintKey, List<T> lstData, bool IsAutoPrintKey = true) { int RtnExe = 0; string Sql = string.Empty; try { if (lstData.Count < 1) return RtnExe; List<T> lstDtSel = new List<T>(); foreach (var item in lstData) { lstDtSel.Add(item); //不能超过一千条,设置1000以内的数值 if (lstDtSel.Count > 800) { //Sql = MySqlEceSql<T>(TbName, PrintKey, lstData,IsAutoPrintKey); Sql = MySqlEceSql<T>(TbName, PrintKey, lstDtSel); if (Sql.Length > 0) { int Add = _db.Execute(Sql); RtnExe = RtnExe + Add; lstDtSel = new List<T>(); Sql = string.Empty; } } } if (lstDtSel.Count > 0) { Sql = MySqlEceSql<T>(TbName, PrintKey, lstDtSel); int Add = _db.Execute(Sql); RtnExe = RtnExe + Add; lstDtSel = new List<T>(); Sql = string.Empty; } } catch (Exception) { throw; } return RtnExe; } #endregion #region SqlServer 批量提交 /// <summary> /// Sql批量提交 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="TbName">表名</param> /// <param name="PrintKey">如果主键不是自增长ID,则可以输入空字符串</param> /// <param name="lstData">需要插入表格内容</param> /// <param name="IsAutoPrintKey">主键是否自增长</param> /// <returns></returns> public int SqlBulkToSQlSERVER_MAIN<T>(string TbName, string PrintKey, List<T> lstData, bool IsAutoPrintKey = true) { int Rtn = 0; try { if (lstData.Count > 300) { SqlBulkToSQl<T>(TbName, lstData); Rtn = lstData.Count(); } else { Rtn= SqlBulkToSQlSERVER<T>(TbName, PrintKey, lstData, IsAutoPrintKey); } } catch (Exception) { throw; } return Rtn; } #region 方法1 ,此方法会造成大量的unused占用内存,但是执行效率高 /// <summary> /// 注意:DataTable中的列需要与数据库表中的列完全一致。,只支持sql servert /// 已自测可用。 /// </summary> /// <param name="conStr">数据库连接串</param> /// <param name="strTableName">数据库中对应的表名</param> /// <param name="dtData">数据集</param> //public void SqlBulkCopyInsert(string conStr, string strTableName, DataTable dtData) public void SqlBulkToSQl<T>(string strTableName, List<T> lstDt) { try { List<T> lstDtSel = new List<T>(); foreach (var item in lstDt) { lstDtSel.Add(item); //不能超过一千条,设置1000以内的数值 if (lstDtSel.Count > 800) { DataTable dtList = ToDataTable<T>(lstDtSel,null); SqlBulkCopyInsert(strTableName, dtList); lstDtSel = new List<T>(); } } if (lstDtSel.Count > 0) { DataTable dtList = ToDataTable<T>(lstDtSel, null); SqlBulkCopyInsert(strTableName, dtList); lstDtSel = new List<T>(); } } catch (Exception ex) { throw (ex); } } /// <summary> /// 注意:DataTable中的列需要与数据库表中的列完全一致。 /// 已自测可用。 /// </summary> /// <param name="conStr">数据库连接串</param> /// <param name="strTableName">数据库中对应的表名</param> /// <param name="dtData">数据集</param> //public void SqlBulkCopyInsert(string conStr, string strTableName, DataTable dtData) public void SqlBulkCopyInsert(string strTableName, DataTable dtData) { try { if (dtData == null || dtData.Rows.Count < 1) { return; } int Ctn = 4; while (Ctn > 1) { try { string conStr = _db.ConnectionString; // eg conStr = "Server=localhost;Database=Test;Uid=sa;Pwd=123456;pooling=true;"; using (SqlBulkCopy sqlRevdBulkCopy = new SqlBulkCopy(conStr)) //引用SqlBulkCopy { sqlRevdBulkCopy.DestinationTableName = strTableName; //数据库中对应的表名 sqlRevdBulkCopy.NotifyAfter = dtData.Rows.Count; //有几行数据 sqlRevdBulkCopy.WriteToServer(dtData); //数据导入数据库 sqlRevdBulkCopy.Close(); //关闭连接 } Ctn = -1; } catch (Exception ex) { Thread.Sleep(200); Ctn--; if (Ctn == 1) { throw (ex); } } } } catch (Exception ex) { throw (ex); } } #endregion #region 方法二,此方法优化了方法1会生成大量unused的缺陷,但是执行效率不如方法1高 /// <summary> /// MySql批量提交 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="TbName">表名</param> /// <param name="PrintKey">如果主键不是自增长ID,则可以输入空字符串</param> /// <param name="lstData">需要插入表格内容</param> /// <param name="IsAutoPrintKey">主键是否自增长</param> /// <returns></returns> public int SqlBulkToSQlSERVER<T>(string TbName, string PrintKey, List<T> lstData, bool IsAutoPrintKey = true) { int RtnExe = 0; string Sql = string.Empty; try { if (lstData.Count < 1) return RtnExe; List<T> lstDtSel = new List<T>(); foreach (var item in lstData) { lstDtSel.Add(item); //不能超过一千条,设置1000以内的数值 if (lstDtSel.Count > 800) { //Sql = MySqlEceSql<T>(TbName, PrintKey, lstData, IsAutoPrintKey); Sql = SqlEceSql<T>(TbName, PrintKey, lstDtSel); if (Sql.Length > 0) { int Add = _db.Execute(Sql); RtnExe = RtnExe + Add; lstDtSel = new List<T>(); Sql = string.Empty; } } } if (lstDtSel.Count > 0) { Sql = SqlEceSql<T>(TbName, PrintKey, lstDtSel); int Add = _db.Execute(Sql); RtnExe = RtnExe + Add; lstDtSel = new List<T>(); Sql = string.Empty; } } catch (Exception) { throw; } return RtnExe; } #endregion #endregion #region 共通 #region 生成Sql执行语句 #region 根据属性生成Mysql语句 /// <summary> /// 根据属性生成Mysql语句 /// </summary> /// <typeparam name="S">源对象类型</typeparam> /// <typeparam name="T">目标对象类型</typeparam> /// <param name="s">源对象</param> /// <param name="t">目标对</param> public static string MySqlEceSql<T>(string TbName, string PrintKey, List<T> lstIqc) { string Sql = string.Empty; try { if (lstIqc.Count < 1) return Sql; T s = lstIqc[0]; PropertyInfo[] pps = GetPropertyInfos(s.GetType()); Sql = Sql + string.Format($" INSERT INTO `{TbName}` ( "); //剔除主键 List<PropertyInfo> lst = new List<PropertyInfo>(); foreach (var item in pps) { if (item.Name.ToUpper().Equals(PrintKey.ToUpper())) { continue; } else { lst.Add(item); } } foreach (var item in lst) { Sql = Sql + string.Format($" `{item.Name} ` ,"); } Sql = Sql.Substring(0, Sql.Length - 1); Sql = Sql + string.Format($" ) values "); foreach (var item in lstIqc) { Sql = Sql + string.Format($" ( "); foreach (var itemP in lst) { var value = item.GetType().GetProperty(itemP.Name).GetValue(item, null); if (itemP.PropertyType.FullName.Contains("System.DateTime")) { value = GetValDateFarmatValue3(value, DateTimeFormat.DateTime); } Sql = Sql + ($" '{value}',"); } Sql = Sql.Substring(0, Sql.Length - 1); Sql = Sql + string.Format($" ) ,"); } Sql = Sql.Substring(0, Sql.Length - 1); } catch (Exception) { throw; } return Sql; } #endregion #region 根据属性生成sql语句 /// <summary> /// 根据属性生成sql语句 /// </summary> /// <typeparam name="S">源对象类型</typeparam> /// <typeparam name="T">目标对象类型</typeparam> /// <param name="s">源对象</param> /// <param name="t">目标对</param> public static string SqlEceSql<T>(string TbName, string PrintKey, List<T> lstIqc) { string Sql = string.Empty; try { if (lstIqc.Count < 1) return Sql; T s = lstIqc[0]; PropertyInfo[] pps = GetPropertyInfos(s.GetType()); Sql = Sql + string.Format($" INSERT INTO {TbName} ( "); //剔除主键 List<PropertyInfo> lst = new List<PropertyInfo>(); foreach (var item in pps) { if (item.Name.ToUpper().Equals(PrintKey.ToUpper())) { continue; } else { lst.Add(item); } } foreach (var item in lst) { Sql = Sql + string.Format($" [{item.Name}],"); } Sql = Sql.Substring(0, Sql.Length - 1); Sql = Sql + string.Format($" ) values "); foreach (var item in lstIqc) { Sql = Sql + string.Format($" ( "); foreach (var itemP in lst) { var value = item.GetType().GetProperty(itemP.Name).GetValue(item, null); if (itemP.PropertyType.FullName.Contains("System.DateTime")) { value = GetValDateFarmatValue3(value, DateTimeFormat.DateTime); } Sql = Sql + ($" '{value}',"); } Sql = Sql.Substring(0, Sql.Length - 1); Sql = Sql + string.Format($" ) ,"); } Sql = Sql.Substring(0, Sql.Length - 1); } catch (Exception) { throw; } return Sql; } /// <summary> /// 时间类型状态 /// </summary> /// <param name="objVal"></param> /// <param name="format"></param> /// <returns></returns> public static string GetValDateFarmatValue3(object objVal, DateTimeFormat format) { if (objVal == null || string.IsNullOrEmpty(objVal.ToString())) { return ""; } else { switch (format) { case DateTimeFormat.DateTime: return GetValDateTime(objVal).ToString("yyyy/MM/dd HH:mm:ss"); case DateTimeFormat.Date: return GetValDateTime(objVal).ToString("yyyy/MM/dd"); case DateTimeFormat.DateStr: return GetValDateTime(objVal).ToString("yyyy年MM月dd日"); case DateTimeFormat.Time: return GetValDateTime(objVal).ToString("HH:mm:ss"); case DateTimeFormat.Hours: return GetValDateTime(objVal).ToString("HH:mm"); default: return GetValDateTime(objVal).ToString("yyyy/MM/dd HH:mm:ss"); } } } /// <summary> /// 将当前值对象转换为DateTime类型 /// </summary> /// <param name="objVal"></param> /// <returns></returns> public static DateTime GetValDateTime(object objVal) { DateTime result = isNotNullVal(objVal) && DateTime.TryParse(objVal.ToString(), out result) ? result : new DateTime(1900, 1, 1); return result; } /// <summary> /// 判断当前值是否为空,不为空true 反false /// </summary> /// <param name="objVal"></param> /// <returns>不为空true 反false</returns> public static bool isNotNullVal(object objVal) { if (objVal != null) { if (objVal.GetType() == typeof(DataTable)) { return (objVal as DataTable).Rows.Count >= 1; } else if (objVal.GetType() == typeof(DataSet)) { return (objVal as DataSet) != null && (objVal as DataSet).Tables.Count >= 1; } else if (objVal.GetType() == typeof(DataRow)) { return (objVal as DataRow) != null; } else if (objVal.GetType() == typeof(DataRow[])) { return (objVal as DataRow[]).Length >= 1; } else if (objVal.GetType() == typeof(Array)) { return (objVal as Array).Length >= 1; } else if (objVal.GetType() == typeof(string[])) { return (objVal as string[]).Length >= 1; } else if (objVal.GetType() == typeof(object[])) { return (objVal as object[]).Length >= 1; } return !string.IsNullOrEmpty(objVal.ToString()); } return false; } #endregion /// <summary> /// 获取类型的属性 /// </summary> /// <param name="type"></param> /// <returns></returns> public static PropertyInfo[] GetPropertyInfos(Type type) { return type.GetProperties(BindingFlags.Public | BindingFlags.Instance); } #endregion #region List<T>转Table /// <summary> /// 将泛型集合类转换成DataTable /// </summary> /// <typeparam name="T">集合项类型</typeparam> /// <param name="list">集合</param> /// <param name="propertyName">需要返回的列的列名</param> /// <returns>数据集(表)</returns> public static DataTable ToDataTable<T>(IList<T> list, params string[] propertyName) { List<string> propertyNameList = new List<string>(); if (propertyName != null) propertyNameList.AddRange(propertyName); DataTable result = new DataTable(); if (list.Count > 0) { PropertyInfo[] propertys = list[0].GetType().GetProperties(); foreach (PropertyInfo pi in propertys) { try { if (propertyNameList.Count == 0) { result.Columns.Add(pi.Name, pi.PropertyType); } else { if (propertyNameList.Contains(pi.Name)) result.Columns.Add(pi.Name, pi.PropertyType); } } catch (Exception) { result.Columns.Add(pi.Name, Type.GetType("System.String")); } } for (int i = 0; i < list.Count; i++) { ArrayList tempList = new ArrayList(); foreach (PropertyInfo pi in propertys) { if (propertyNameList.Count == 0) { object obj = pi.GetValue(list[i], null); tempList.Add(obj); } else { if (propertyNameList.Contains(pi.Name)) { object obj = pi.GetValue(list[i], null); tempList.Add(obj); } } } object[] array = tempList.ToArray(); result.LoadDataRow(array, true); } } return result; } #endregion #endregion #endregion