133 lines
5.2 KiB
C#
133 lines
5.2 KiB
C#
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<T>(this DbContext context, IEnumerable<T> entities)
|
|
{
|
|
if (entities != null && entities.Any())
|
|
{
|
|
var conn = context.Database.GetDbConnection() as MySqlConnection;
|
|
BulkInsert(conn, entities);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Inserts entities into table <typeparamref name="T"/>s (by default).
|
|
/// </summary>
|
|
/// <typeparam name="T">The type being inserted.</typeparam>
|
|
/// <param name="connection">Open SqlConnection</param>
|
|
/// <param name="data">Entities to insert</param>
|
|
/// <param name="transaction">The transaction to run under, null (the default) if none</param>
|
|
/// <param name="batchSize">Number of bulk items inserted together, 0 (the default) if all</param>
|
|
/// <param name="bulkCopyTimeout">Number of seconds before bulk command execution timeout, 30 (the default)</param>
|
|
private static void BulkInsert<T>(MySqlConnection connection, IEnumerable<T> data, IDbTransaction transaction = null)
|
|
{
|
|
BulkInsert(connection, typeof(T), data.Cast<object>(), transaction);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Inserts entities into table.
|
|
/// by default, the table is named after the data type specified.
|
|
/// </summary>
|
|
/// <param name="connection">Open SqlConnection</param>
|
|
/// <param name="type">The type being inserted.</param>
|
|
/// <param name="data">Entities to insert</param>
|
|
/// <param name="transaction">The transaction to run under, null (the default) if none</param>
|
|
/// <param name="batchSize">Number of bulk items inserted together, 0 (the default) if all</param>
|
|
/// <param name="bulkCopyTimeout">Number of seconds before bulk command execution timeout, 30 (the default)</param>
|
|
private static void BulkInsert(MySqlConnection connection, Type type, IEnumerable<object> 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<T>(StringBuilder sb, IEnumerable<T> data, IList<PropertyInfo> 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);
|
|
}
|
|
}
|
|
}
|