Fastest Way of Inserting in Entity Framework

前端 未结 30 2192
鱼传尺愫
鱼传尺愫 2020-11-21 05:23

I\'m looking for the fastest way of inserting into Entity Framework.

I\'m asking this because of the scenario where you have an active TransactionScope a

30条回答
  •  南笙
    南笙 (楼主)
    2020-11-21 05:48

    [NEW SOLUTION FOR POSTGRESQL] Hey, I know it's quite an old post, but I have recently run into similar problem, but we were using Postgresql. I wanted to use effective bulkinsert, what turned out to be pretty difficult. I haven't found any proper free library to do so on this DB. I have only found this helper: https://bytefish.de/blog/postgresql_bulk_insert/ which is also on Nuget. I have written a small mapper, which auto mapped properties the way Entity Framework:

    public static PostgreSQLCopyHelper CreateHelper(string schemaName, string tableName)
            {
                var helper = new PostgreSQLCopyHelper("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;
            }
    

    I use it the following way (I had entity named Undertaking):

    var undertakingHelper = BulkMapper.CreateHelper("dbo", nameof(Model.Undertaking));
    undertakingHelper.SaveAll(transaction.UnderlyingTransaction.Connection as Npgsql.NpgsqlConnection, undertakingsToAdd));
    

    I showed an example with transaction, but it can also be done with normal connection retrieved from context. undertakingsToAdd is enumerable of normal entity records, which I want to bulkInsert into DB.

    This solution, to which I've got after few hours of research and trying, is as you could expect much faster and finally easy to use and free! I really advice you to use this solution, not only for the reasons mentioned above, but also because it's the only one with which I had no problems with Postgresql itself, many other solutions work flawlessly for example with SqlServer.

提交回复
热议问题