Example #1
0
        protected internal virtual BulkOptions SetDefaults(BulkOptions defaultOptions)
        {
            if (!FieldsSelector.HasValue)
            {
                FieldsSelector = defaultOptions.FieldsSelector;
            }

            if (!CaseSensitiveFieldsMatching.HasValue)
            {
                CaseSensitiveFieldsMatching = defaultOptions.CaseSensitiveFieldsMatching;
            }

            if (!CreateTable.HasValue)
            {
                CreateTable = defaultOptions.CreateTable;
            }

            if (!IgnoreDataReaderSchemaTable.HasValue)
            {
                IgnoreDataReaderSchemaTable = defaultOptions.IgnoreDataReaderSchemaTable;
            }

            if (!CheckTableIfNotExistsBeforeCreation.HasValue)
            {
                CheckTableIfNotExistsBeforeCreation = defaultOptions.CheckTableIfNotExistsBeforeCreation;
            }

            return(this);
        }
Example #2
0
        public EntityMetadataColumnSetupProvider(IEntityType entity, EntityState state, BulkOptions bulkOptions)
        {
            _bulkOptions = bulkOptions;

            SchemaName = entity.GetSchema();
            TableName  = entity.GetTableName();

            var properties = entity.GetProperties();

            if (state == EntityState.Deleted)
            {
                properties = properties.Where(p => p.IsPrimaryKey());
            }

            if (_bulkOptions.ShadowPropertyAccessor == null)
            {
                properties = properties.Where(p => entity.FindDiscriminatorProperty() == p || !p.IsShadowProperty());
            }

            var columns = properties.Select((p, i) => CreateColumnSetup(entity, p, i, state, _bulkOptions)).Where(p => p.ValueDirection != ValueDirection.None);

            if (!bulkOptions.PropagateValues)
            {
                columns = columns.Where(p => p.ValueDirection.HasFlag(ValueDirection.Write));
            }

            _columns = columns.ToImmutableList();
        }
Example #3
0
        protected override BulkOptions SetDefaults(BulkOptions defaultOptions)
        {
            base.SetDefaults(defaultOptions);
            if (!(defaultOptions is SqlBulkOptions opt))
            {
                return(this);
            }

            if (!BatchSize.HasValue)
            {
                BatchSize = opt.BatchSize;
            }

            if (!BulkCopyTimeout.HasValue)
            {
                BulkCopyTimeout = opt.BulkCopyTimeout;
            }

            if (!SqlBulkCopyOptions.HasValue)
            {
                SqlBulkCopyOptions = opt.SqlBulkCopyOptions;
            }

            if (!EnableStreaming.HasValue)
            {
                EnableStreaming = opt.EnableStreaming;
            }

            if (ColumnDefinitionOptions == null)
            {
                ColumnDefinitionOptions = opt.ColumnDefinitionOptions?.Clone();
            }

            return(this);
        }
Example #4
0
        /// <summary>
        /// </summary>
        /// <param name="mapping"></param>
        /// <param name="tableName"></param>
        /// <param name="operationType"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        internal static string BuildStagingTableCommand(this IEntityMapping mapping, string tableName, Operation operationType,
                                                        BulkOptions options)
        {
            var paramList = mapping
                            .GetPropertiesByOperation(operationType)
                            .ToList();

            if (paramList.All(s => s.IsPk && s.IsDbGenerated) &&
                operationType == Operation.Update)
            {
                return(null);
            }

            var paramColumns = paramList
                               .Select(column => $"{Source}.[{column.ColumnName}]")
                               .ToList();

            if (mapping.WillOutputGeneratedValues(options))
            {
                paramColumns.Add($"1 as [{Identity}]");
            }

            var paramListConcatenated = string.Join(", ", paramColumns);

            return($"SELECT TOP 0 {paramListConcatenated} INTO {tableName} FROM {mapping.FullTableName} AS A " +
                   $"LEFT JOIN {mapping.FullTableName} AS {Source} ON 1 = 2");
        }
Example #5
0
 protected BulkOptions(BulkOptions bulkOptions)
 {
     this.FieldsSelector = bulkOptions.FieldsSelector;
     this.CaseSensitiveFieldsMatching = bulkOptions.CaseSensitiveFieldsMatching;
     this.CreateTable = bulkOptions.CreateTable;
     this.IgnoreDataReaderSchemaTable         = bulkOptions.IgnoreDataReaderSchemaTable;
     this.CheckTableIfNotExistsBeforeCreation = bulkOptions.CheckTableIfNotExistsBeforeCreation;
 }
        public void BulkInsert(IDbConnection dbConnection, DataTable dataTable, BulkOptions bulkOptions)
        {
            NpgsqlConnection connection = (NpgsqlConnection)dbConnection;

            using (NpgsqlBinaryImporter writer = connection.BeginBinaryImport(BuildCopyFromCommand(dataTable)))
            {
                foreach (DataRow dataRow in dataTable.Rows)
                {
                    writer.WriteRow(dataRow.ItemArray);
                }
            }
        }
Example #7
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="context"></param>
        /// <param name="collection"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        int IBulkOperation.CommitTransaction <TEntity>(IDbContextWrapper context, IEnumerable <TEntity> collection,
                                                       BulkOptions options)
        {
            var entityList = collection.ToList();

            if (!entityList.Any())
            {
                return(entityList.Count);
            }

            try
            {
                //Return generated IDs for bulk inserted elements.
                if (options.HasFlag(BulkOptions.OutputIdentity))
                {
                    var tmpTableName = context.EntityMapping.RandomTableName();
                    //Create temporary table.
                    context.ExecuteSqlCommand(context.EntityMapping.CreateTempTable(tmpTableName, OperationType.Insert, options));

                    //Bulk inset data to temporary temporary table.
                    context.BulkInsertToTable(entityList, tmpTableName, OperationType.Insert, options);

                    var tmpOutputTableName = context.EntityMapping.RandomTableName();
                    //Copy data from temporary table to destination table with ID output to another temporary table.
                    var commandText = context.EntityMapping.GetInsertIntoStagingTableCmd(tmpOutputTableName,
                                                                                         tmpTableName, context.EntityMapping.Pks.First().ColumnName, OperationType.Insert, options);
                    context.ExecuteSqlCommand(commandText);

                    //Load generated IDs from temporary output table into the entities.
                    context.LoadFromTmpOutputTable(tmpOutputTableName, context.EntityMapping.Pks.First(), entityList);
                }
                else
                {
                    //Bulk inset data to temporary destination table.
                    context.BulkInsertToTable(entityList, context.EntityMapping.FullTableName, OperationType.Insert, options);
                }

                //Commit if internal transaction exists.
                context.Commit();
                return(entityList.Count);
            }
            catch (Exception)
            {
                //Rollback if internal transaction exists.
                context.Rollback();
                throw;
            }
        }
Example #8
0
        public void BulkInsert(IDbConnection dbConnection, DataTable dataTable, BulkOptions bulkOptions)
        {
            SqlConnection conn = (SqlConnection)dbConnection;

            SqlBulkCopyOptions options     = SqlBulkCopyOptions.CheckConstraints | SqlBulkCopyOptions.UseInternalTransaction;
            SqlTransaction     transaction = null;

            SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(conn, options, transaction);

            sqlBulkCopy.DestinationTableName = dataTable.TableName;
            sqlBulkCopy.BulkCopyTimeout      = bulkOptions.TimeoutInSeconds;

            foreach (DataColumn column in dataTable.Columns)
            {
                sqlBulkCopy.ColumnMappings.Add(column.ColumnName, column.ColumnName);
            }

            sqlBulkCopy.WriteToServer(dataTable);
        }
Example #9
0
 protected internal SqlBulkOptions(BulkOptions bulkOptions)
     : base(bulkOptions)
 {
     if (bulkOptions is SqlBulkOptions opt)
     {
         this.BatchSize               = opt.BatchSize;
         this.BulkCopyTimeout         = opt.BulkCopyTimeout;
         this.SqlBulkCopyOptions      = opt.SqlBulkCopyOptions;
         this.EnableStreaming         = opt.EnableStreaming;
         this.ColumnDefinitionOptions = opt.ColumnDefinitionOptions;
     }
     else
     {
         this.BatchSize               = null;
         this.BulkCopyTimeout         = null;
         this.SqlBulkCopyOptions      = null;
         this.EnableStreaming         = null;
         this.ColumnDefinitionOptions = null;
     }
 }
Example #10
0
 protected override ConnectionContext GetConnectionContext(DbConnection connection, QueryOptions queryOptions, BulkOptions bulkOptions, ReadOptions readOptions)
 {
     return(new SqlConnectionContext(this, (SqlConnection)connection, queryOptions, bulkOptions, readOptions));
 }
Example #11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mapping"></param>
        /// <param name="tmpOutputTableName"></param>
        /// <param name="tmpTableName"></param>
        /// <param name="identityColumn"></param>
        /// <returns></returns>
        internal static string GetInsertIntoStagingTableCmd(this IEntityMapping mapping, string tmpOutputTableName,
                                                            string tmpTableName, string identityColumn, OperationType operationType, BulkOptions options)
        {
            var columns = mapping.Properties
                          .FilterPropertiesByOperation(operationType)
                          .Select(propertyMapping => propertyMapping.ColumnName)
                          .ToList();

            var comm = GetOutputCreateTableCmd(tmpOutputTableName, identityColumn)
                       + BuildInsertIntoSet(columns, identityColumn, mapping.FullTableName)
                       + $"OUTPUT INSERTED.{identityColumn} INTO "
                       + tmpOutputTableName + $"([{identityColumn}]) "
                       + BuildSelectSet(columns, identityColumn)
                       + $" FROM {tmpTableName} AS Source; "
                       + GetDropTableCommand(tmpTableName);

            return(comm);
        }
Example #12
0
 internal static string BuildMergeCommand(this IDbContextWrapper context, string tmpTableName, OperationType operationType, BulkOptions options)
 {
     return($"MERGE INTO {context.EntityMapping.FullTableName} WITH (HOLDLOCK) AS Target USING {tmpTableName} AS Source " +
            $"{context.EntityMapping.PrimaryKeysComparator()} WHEN MATCHED THEN UPDATE {context.EntityMapping.BuildUpdateSet(operationType, options)}; " +
            GetDropTableCommand(tmpTableName));
 }
 protected internal NpgsqlTransactionContext(ContextProvider contextProvider, NpgsqlTransaction transaction,
                                             QueryOptions queryOptions, BulkOptions bulkOptions, ReadOptions readOptions)
     : base(contextProvider, transaction, queryOptions, bulkOptions, readOptions)
 {
 }
        internal static IEnumerable <IPropertyMapping> GetPropertiesByOptions(this IEntityMapping mapping, BulkOptions options)
        {
            if (options.HasFlag(BulkOptions.OutputIdentity) && options.HasFlag(BulkOptions.OutputComputed))
            {
                return(mapping.Properties.Where(property => property.IsDbGenerated));
            }
            if (options.HasFlag(BulkOptions.OutputIdentity))
            {
                return(mapping.Properties.Where(property => property.IsPk && property.IsDbGenerated));
            }
            if (options.HasFlag(BulkOptions.OutputComputed))
            {
                return(mapping.Properties.Where(property => !property.IsPk && property.IsDbGenerated));
            }

            return(mapping.Properties);
        }
 protected internal NpgsqlConnectionStringContext(ContextProvider contextProvider, string connectionString,
                                                  QueryOptions queryOptions, BulkOptions bulkOptions, ReadOptions readOptions)
     : base(contextProvider, connectionString, queryOptions, bulkOptions, readOptions)
 {
 }
Example #16
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <param name="collection"></param>
        /// <param name="options"></param>
        /// <typeparam name="TEntity"></typeparam>
        /// <returns></returns>
        int IBulkOperation.CommitTransaction <TEntity>(IDbContextWrapper context, IEnumerable <TEntity> collection, BulkOptions options)
        {
            var tmpTableName = context.EntityMapping.RandomTableName();
            var entityList   = collection.ToList();

            if (!entityList.Any())
            {
                return(entityList.Count);
            }

            try
            {
                //Create temporary table.
                context.ExecuteSqlCommand(context.EntityMapping.CreateTempTable(tmpTableName, OperationType.Update, options));

                //Bulk inset data to temporary temporary table.
                context.BulkInsertToTable(entityList, tmpTableName, OperationType.Update, options);

                //Copy data from temporary table to destination table.
                var affectedRows = context.ExecuteSqlCommand(context.BuildMergeCommand(tmpTableName, OperationType.Update, options));

                //Commit if internal transaction exists.
                context.Commit();
                return(affectedRows);
            }
            catch (Exception)
            {
                //Rollback if internal transaction exists.
                context.Rollback();
                throw;
            }
        }
Example #17
0
 protected override ConnectionStringContext GetConnectionStringContext(string connectionString, QueryOptions queryOptions, BulkOptions bulkOptions, ReadOptions readOptions)
 {
     return(new SqlConnectionStringContext(this, connectionString, queryOptions, bulkOptions, readOptions));
 }
Example #18
0
 internal static IEnumerable <IPropertyMapping> FilterPropertiesByOptions(this IEnumerable <IPropertyMapping> propertyMappings, BulkOptions options)
 {
     if (!options.HasFlag(BulkOptions.KeepForeingKeys))
     {
         return(propertyMappings.Where(property => !property.IsFk));
     }
     return(propertyMappings);
 }
Example #19
0
        ///  <summary>
        ///  </summary>
        /// <param name="context"></param>
        /// <param name="collection"></param>
        /// <param name="options"></param>
        /// <typeparam name="TEntity"></typeparam>
        ///  <returns></returns>
        int IBulkOperation.CommitTransaction <TEntity>(IDbContextWrapper context, IEnumerable <TEntity> collection, BulkOptions options)
        {
            var tmpTableName = context.EntityMapping.RandomTableName();
            var entityList   = collection.ToList();

            if (!entityList.Any())
            {
                return(entityList.Count);
            }

            try
            {
                //Create temporary table with only the primary keys.
                context.ExecuteSqlCommand(context.EntityMapping.CreateTempTable(tmpTableName, OperationType.Delete));

                //Bulk inset data to temporary table.
                context.BulkInsertToTable(entityList, tmpTableName, OperationType.Delete);

                //Merge delete items from the target table that matches ids from the temporary table.
                var affectedRows = context.ExecuteSqlCommand(context.BuildDeleteCommand(tmpTableName));

                //Commit if internal transaction exists.
                context.Commit();
                return(affectedRows);
            }
            catch (Exception)
            {
                //Rollback if internal transaction exists.
                context.Rollback();
                throw;
            }
        }
        internal static void BulkInsertToTable <TEntity>(this IDbContextWrapper context, IList <TEntity> entities,
                                                         string tableName, Operation operationType, BulkOptions options) where TEntity : class
        {
            var properties = context.EntityMapping
                             .GetPropertiesByOperation(operationType)
                             .ToList();

            if (context.EntityMapping.WillOutputGeneratedValues(options))
            {
                properties.Add(new PropertyMapping
                {
                    ColumnName   = SqlHelper.Identity,
                    PropertyName = SqlHelper.Identity
                });
            }

            using (var bulkcopy = new SqlBulkCopy((SqlConnection)context.Connection, SqlBulkCopyOptions.Default,
                                                  (SqlTransaction)context.Transaction))
            {
                foreach (var column in properties)
                {
                    bulkcopy.ColumnMappings.Add(column.ColumnName, column.ColumnName);
                }

                bulkcopy.BatchSize            = context.BatchSize;
                bulkcopy.DestinationTableName = tableName;
                bulkcopy.BulkCopyTimeout      = context.Timeout;
                bulkcopy.WriteToServer(entities.ToDataReader(context.EntityMapping, properties));
            }
        }
Example #21
0
        internal static void BulkInsertToTable <TEntity>(this IDbContextWrapper context, IEnumerable <TEntity> entities,
                                                         string tableName, OperationType operationType, BulkOptions options) where TEntity : class
        {
            var properties = context.EntityMapping.Properties
                             .FilterPropertiesByOperation(operationType);
            var dataReader = entities.ToDataReader(context.EntityMapping, operationType, options);

            using (var bulkcopy = new SqlBulkCopy((SqlConnection)context.Connection,
                                                  SqlBulkCopyOptions.Default | SqlBulkCopyOptions.KeepIdentity,
                                                  (SqlTransaction)context.Transaction))
            {
                foreach (var column in properties)
                {
                    bulkcopy.ColumnMappings.Add(column.ColumnName, column.ColumnName);
                }

                bulkcopy.DestinationTableName = tableName;
                bulkcopy.BulkCopyTimeout      = context.Connection.ConnectionTimeout;
                bulkcopy.WriteToServer(dataReader);
            }
        }
Example #22
0
 protected override TransactionContext GetTransactionContext(DbTransaction transaction, QueryOptions queryOptions, BulkOptions bulkOptions, ReadOptions readOptions)
 {
     return(new SqlTransactionContext(this, (SqlTransaction)transaction, queryOptions, bulkOptions, readOptions));
 }
 internal static bool WillOutputGeneratedValues(this IEntityMapping mapping, BulkOptions options)
 {
     return(options.HasFlag(BulkOptions.OutputIdentity) && mapping.HasGeneratedKeys ||
            options.HasFlag(BulkOptions.OutputComputed) && mapping.HasComputedColumns);
 }
Example #24
0
 protected override BulkCopy GetBulkCopy(ScopedContext context, DbDataReader reader, string destinationTable, BulkOptions bulkOptions, params string[] fields)
 {
     return(new MsSqlBulkCopy(context, reader, destinationTable, (SqlBulkOptions)bulkOptions, fields));
 }
Example #25
0
        /// <summary>
        /// </summary>
        /// <param name="context"></param>
        /// <param name="collection"></param>
        /// <param name="operation"></param>
        /// <param name="options"></param>
        /// <typeparam name="TEntity"></typeparam>
        /// <returns></returns>
        internal static int CommitTransaction <TEntity>(this IDbContextWrapper context, IEnumerable <TEntity> collection, Operation operation,
                                                        BulkOptions options = BulkOptions.Default) where TEntity : class
        {
            var stagingTableName          = context.EntityMapping.RandomTableName();
            var willOutputGeneratedValues = context.EntityMapping.WillOutputGeneratedValues(options);
            var entityList = collection.ToList();

            if (!entityList.Any())
            {
                return(entityList.Count);
            }

            try
            {
                var outputTableName = willOutputGeneratedValues
                    ? context.EntityMapping.RandomTableName()
                    : null;
                var generatedColumns = willOutputGeneratedValues
                    ? context.EntityMapping.GetPropertiesByOptions(options).ToList()
                    : null;

                //Create temporary table.
                var stagingTableCommand = context.EntityMapping
                                          .BuildStagingTableCommand(stagingTableName, operation, options);

                if (string.IsNullOrEmpty(stagingTableCommand))
                {
                    context.Rollback();
                    return(SqlHelper.NoRowsAffected);
                }

                context.ExecuteSqlCommand(stagingTableCommand);

                //Bulk inset data to temporary staging table.
                context.BulkInsertToTable(entityList, stagingTableName, operation, options);

                if (willOutputGeneratedValues)
                {
                    context.ExecuteSqlCommand(SqlHelper.BuildOutputTableCommand(outputTableName,
                                                                                context.EntityMapping, generatedColumns));
                }

                //Copy data from temporary table to destination table.
                var mergeCommand = context.BuildMergeCommand(stagingTableName, operation);
                if (willOutputGeneratedValues)
                {
                    mergeCommand += SqlHelper.BuildMergeOutputSet(outputTableName, generatedColumns);
                }
                mergeCommand += SqlHelper.GetDropTableCommand(stagingTableName);
                var affectedRows = context.ExecuteSqlCommand(mergeCommand);

                if (willOutputGeneratedValues)
                {
                    //Load generated values from temporary output table into the entities.
                    context.LoadFromOutputTable(outputTableName, generatedColumns, entityList);
                }

                //Commit if internal transaction exists.
                context.Commit();
                return(affectedRows);
            }
            catch (Exception)
            {
                //Rollback if internal transaction exists.
                context.Rollback();
                throw;
            }
        }
Example #26
0
 protected override BulkOptions GetTyped(BulkOptions options, out bool needClone)
 {
     needClone = false;
     return(new SqlBulkOptions(options));
 }
Example #27
0
 protected internal NpgsqlBulkOptions(BulkOptions bulkOptions)
     : base(bulkOptions)
 {
 }
Example #28
0
        /// <summary>
        /// </summary>
        /// <param name="mapping"></param>
        /// <param name="tableName"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        internal static string CreateTempTable(this IEntityMapping mapping, string tableName, OperationType operationType, BulkOptions options)
        {
            var columns = mapping.Properties
                          .FilterPropertiesByOperation(operationType)
                          .ToList();

            var paramList = columns.Select(column => $"[{column.ColumnName}]")
                            .ToList();
            var paramListConcatenated = string.Join(", ", paramList);

            return($"SELECT {paramListConcatenated} INTO {tableName} FROM {mapping.TableName} WHERE 1 = 2");
        }
Example #29
0
        /// <summary>
        /// </summary>
        /// <param name="mapping"></param>
        /// <returns></returns>
        private static string BuildUpdateSet(this IEntityMapping mapping, OperationType operationType, BulkOptions options)
        {
            var command    = new StringBuilder();
            var parameters = new List <string>();

            command.Append("SET ");
            var properties = mapping.Properties
                             .FilterPropertiesByOperation(operationType);

            foreach (var column in properties)
            {
                if (column.IsPk)
                {
                    continue;
                }

                parameters.Add($"[{Target}].[{column.ColumnName}] = [{Source}].[{column.ColumnName}]");
            }

            command.Append(string.Join(", ", parameters) + " ");

            return(command.ToString());
        }
Example #30
0
 protected override BulkOptions SetDefaults(BulkOptions defaultOptions)
 {
     base.SetDefaults(defaultOptions);
     return(this);
 }