using BaseOUDAL.EFExtensions; using Dapper; using MySqlConnector; using System.Data; using System.Reflection; using System.Text; namespace YLErp.BLL { public static class MySqlBulkExtensions { public static void BulkInsert(this DbContext context, IEnumerable entities) { if (entities != null && entities.Any()) { var conn = context.Database.GetDbConnection() as MySqlConnection; BulkInsert(conn, entities); } } /// /// Inserts entities into table s (by default). /// /// The type being inserted. /// Open SqlConnection /// Entities to insert /// The transaction to run under, null (the default) if none /// Number of bulk items inserted together, 0 (the default) if all /// Number of seconds before bulk command execution timeout, 30 (the default) private static void BulkInsert(MySqlConnection connection, IEnumerable data, IDbTransaction transaction = null) { BulkInsert(connection, typeof(T), data.Cast(), transaction); } /// /// Inserts entities into table. /// by default, the table is named after the data type specified. /// /// Open SqlConnection /// The type being inserted. /// Entities to insert /// The transaction to run under, null (the default) if none /// Number of bulk items inserted together, 0 (the default) if all /// Number of seconds before bulk command execution timeout, 30 (the default) private static void BulkInsert(MySqlConnection connection, Type type, IEnumerable data, IDbTransaction transaction = null) { var tableName = TableMapper.GetTableName(type); var allProperties = PropertiesCache.TypePropertiesCache(type); var computedProperties = PropertiesCache.ComputedPropertiesCache(type); var columns = PropertiesCache.GetColumnNamesCache(type); var selProperties = allProperties.Except(computedProperties).ToList(); if (!selProperties.Any()) { return; } var selcols = string.Join(", ", selProperties.Select(property => $"`{columns[property.Name]}`")); var sCommand = new StringBuilder(); sCommand.Append("INSERT INTO `").Append(tableName) .Append("` (").Append(selcols).Append(") VALUES "); DumpInertValues(sCommand, data, selProperties).AppendLine(";"); var sql = sCommand.ToString(); System.Diagnostics.Debug.WriteLine("$$$$$$$$$$"); System.Diagnostics.Debug.WriteLine(sql); connection.Execute(sql, null, transaction); } private static StringBuilder DumpInertValues(StringBuilder sb, IEnumerable data, IList properties) { System.Diagnostics.Debug.Assert(properties.Count > 0); var typeCasts = new Type[properties.Count]; for (var i = 0; i < properties.Count; i++) { if (properties[i].PropertyType.IsEnum) { typeCasts[i] = Enum.GetUnderlyingType(properties[i].PropertyType); } else { typeCasts[i] = null; } } foreach (var item in data) { sb.AppendLine().Append("("); for (var i = 0; i < properties.Count; i++) { var value = properties[i].GetValue(item, null); if (value == null) { sb.Append("NULL"); } else if (value is string str) { sb.Append('\'').Append(MySqlHelper.EscapeString(str)).Append('\''); } else if (value is DateTime dt) { sb.Append('\'').Append(dt.ToString("yyyy-MM-dd HH:mm:ss")).Append('\''); } else if (value is double dd) { sb.Append(double.IsNaN(dd) ? 0 : dd); } else if (typeCasts[i] != null) { sb.Append(Convert.ChangeType(value, typeCasts[i])); } else { sb.Append(value); } sb.Append(','); } sb.Remove(sb.Length - 1, 1).Append("),"); } return sb.Remove(sb.Length - 1, 1); } } }