[NUEVA SOLUCIÓN PARA POSTGRESQL] Hola, sé que es una publicación bastante antigua, pero recientemente me he encontrado con un problema similar, pero estábamos usando Postgresql. Quería usar Bulkinsert efectivo, lo que resultó ser bastante difícil. No he encontrado ninguna biblioteca gratuita adecuada para hacerlo en este DB. Solo he encontrado este ayudante:
https://bytefish.de/blog/postgresql_bulk_insert/
que también está en Nuget. He escrito un pequeño mapeador, que asigna automáticamente propiedades de la forma en que Entity Framework:
public static PostgreSQLCopyHelper<T> CreateHelper<T>(string schemaName, string tableName)
{
var helper = new PostgreSQLCopyHelper<T>("dbo", "\"" + tableName + "\"");
var properties = typeof(T).GetProperties();
foreach(var prop in properties)
{
var type = prop.PropertyType;
if (Attribute.IsDefined(prop, typeof(KeyAttribute)) || Attribute.IsDefined(prop, typeof(ForeignKeyAttribute)))
continue;
switch (type)
{
case Type intType when intType == typeof(int) || intType == typeof(int?):
{
helper = helper.MapInteger("\"" + prop.Name + "\"", x => (int?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
case Type stringType when stringType == typeof(string):
{
helper = helper.MapText("\"" + prop.Name + "\"", x => (string)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
case Type dateType when dateType == typeof(DateTime) || dateType == typeof(DateTime?):
{
helper = helper.MapTimeStamp("\"" + prop.Name + "\"", x => (DateTime?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
case Type decimalType when decimalType == typeof(decimal) || decimalType == typeof(decimal?):
{
helper = helper.MapMoney("\"" + prop.Name + "\"", x => (decimal?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
case Type doubleType when doubleType == typeof(double) || doubleType == typeof(double?):
{
helper = helper.MapDouble("\"" + prop.Name + "\"", x => (double?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
case Type floatType when floatType == typeof(float) || floatType == typeof(float?):
{
helper = helper.MapReal("\"" + prop.Name + "\"", x => (float?)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
case Type guidType when guidType == typeof(Guid):
{
helper = helper.MapUUID("\"" + prop.Name + "\"", x => (Guid)typeof(T).GetProperty(prop.Name).GetValue(x, null));
break;
}
}
}
return helper;
}
Lo uso de la siguiente manera (tenía una entidad llamada Undertaking):
var undertakingHelper = BulkMapper.CreateHelper<Model.Undertaking>("dbo", nameof(Model.Undertaking));
undertakingHelper.SaveAll(transaction.UnderlyingTransaction.Connection as Npgsql.NpgsqlConnection, undertakingsToAdd));
Mostré un ejemplo con la transacción, pero también se puede hacer con una conexión normal recuperada del contexto. enterprisesToAdd es enumerable de registros de entidades normales, que quiero insertar a granel en DB.
¡Esta solución, que obtuve después de algunas horas de investigación y prueba, es como podría esperarse mucho más rápido y finalmente fácil de usar y gratis! Realmente te recomiendo que uses esta solución, no solo por las razones mencionadas anteriormente, sino también porque es la única con la que no tuve problemas con Postgresql, muchas otras soluciones funcionan perfectamente, por ejemplo con SqlServer.