コード例 #1
0
        /// <summary>
        /// Builds the insert set.
        /// </summary>
        /// <param name="bulkMetadata">The bulk metadata.</param>
        /// <returns></returns>
        private static string BuildInsertSet(BulkRuntimeTypeHandleMetadata bulkMetadata)
        {
            var command       = new StringBuilder();
            var insertColumns = new List <string>();

            command.Append("INSERT (");

            foreach (var column in bulkMetadata.Columns)
            {
                if ((bulkMetadata.IdentityColumn != null && column != bulkMetadata.IdentityColumn) || bulkMetadata.IdentityColumn == null)
                {
                    if (column.Item1 != "InternalId")
                    {
                        insertColumns.Add($"[{column.Item1 }]");
                    }
                }
            }

            command.Append(string.Join(", ", insertColumns));
            command.Append(") values (");
            command.Append(string.Join(", ", insertColumns));
            command.Append(")");

            return(command.ToString());
        }
コード例 #2
0
        /// <summary>
        /// Shreds the object.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="bulkRuntimeTypeHandleMetadata">The bulk runtime type handle metadata.</param>
        /// <param name="instance">The instance.</param>
        /// <param name="counter">The counter.</param>
        /// <param name="outputIdentityDic">The output identity dic.</param>
        /// <param name="identifierOnly">if set to <c>true</c> [identifier only].</param>
        /// <returns></returns>
        private static object[] ShredObject <TEntity>(BulkRuntimeTypeHandleMetadata bulkRuntimeTypeHandleMetadata, TEntity instance, int counter, Dictionary <int, TEntity> outputIdentityDic, bool identifierOnly) where TEntity : class
        {
            var length = bulkRuntimeTypeHandleMetadata.Columns.Length;

            var values = new object[length];

            var index = 0;

            foreach (var pInfo in bulkRuntimeTypeHandleMetadata.PropertyInfos)
            {
                if (bulkRuntimeTypeHandleMetadata.Columns[index].Item1 == "InternalId")
                {
                    values[index++] = counter;
                    outputIdentityDic.Add(counter, instance);
                }
                if (identifierOnly)
                {
                    values[index++] = bulkRuntimeTypeHandleMetadata.Columns[index].Item1 == bulkRuntimeTypeHandleMetadata.IdentityColumn.Item1 ? pInfo.GetValue(instance, null) : null;
                }
                else
                {
                    values[index++] = pInfo.GetValue(instance, null);
                }
            }

            return(values);
        }
コード例 #3
0
        /// <summary>
        /// Gets the temporary data table.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="bulkRuntimeTypeHandleMetadata">The bulk runtime type handle metadata.</param>
        /// <param name="outputIdentity">The output identity.</param>
        /// <returns></returns>
        private static DataTable GetTemporaryDataTable(Type type, out BulkRuntimeTypeHandleMetadata bulkRuntimeTypeHandleMetadata, bool?outputIdentity = null)
        {
            bulkRuntimeTypeHandleMetadata = GetBulkRuntimeTypeHandleMetadata(type, outputIdentity);

            var table = new DataTable(bulkRuntimeTypeHandleMetadata.Name);

            foreach (var info in bulkRuntimeTypeHandleMetadata.Columns)
            {
                table.Columns.Add(new DataColumn(info.Item1, info.Item2));
            }

            return(table);
        }
コード例 #4
0
        /// <summary>
        /// Checks the delete table query.
        /// </summary>
        /// <param name="bulkMetadata">The bulk metadata.</param>
        private static void CheckDeleteTableQuery(BulkRuntimeTypeHandleMetadata bulkMetadata)
        {
            if (!string.IsNullOrEmpty(bulkMetadata.DeleteQuery))
            {
                return;
            }

            var query = $@"MERGE INTO {bulkMetadata.Name} WITH (HOLDLOCK) AS Target 
                            USING #{bulkMetadata.Name} AS Source 
                            {BuildJoinConditionsForUpdateOrInsert(bulkMetadata)} 
                            WHEN MATCHED THEN DELETE; DROP TABLE #{bulkMetadata.Name};";

            bulkMetadata.DeleteQuery = query;
        }
コード例 #5
0
        /// <summary>
        /// Checks the insert or update table query.
        /// </summary>
        /// <param name="bulkMetadata">The bulk metadata.</param>
        private static void CheckInsertOrUpdateTableQuery(BulkRuntimeTypeHandleMetadata bulkMetadata)
        {
            if (!string.IsNullOrEmpty(bulkMetadata.InsertOrUpdateQuery))
            {
                return;
            }

            var query = $@"MERGE INTO {bulkMetadata.Name} WITH (HOLDLOCK) AS Target 
                            USING #{bulkMetadata.Name} AS Source 
                            {BuildJoinConditionsForUpdateOrInsert(bulkMetadata)} 
                            WHEN MATCHED THEN {BuildUpdateSet(bulkMetadata)}
                            WHEN NOT MATCHED BY TARGET THEN {BuildInsertSet(bulkMetadata)}";

            bulkMetadata.InsertOrUpdateQuery = query;
        }
コード例 #6
0
        /// <summary>
        /// Gets the bulk runtime type handle metadata.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="outputIdentity">The output identity.</param>
        /// <returns></returns>
        private static BulkRuntimeTypeHandleMetadata GetBulkRuntimeTypeHandleMetadata(Type type, bool?outputIdentity = null)
        {
            if (BulkOperationsCache.TryGetValue(type.TypeHandle,
                                                out var bulkRuntimeTypeHandleMetadata))
            {
                return(bulkRuntimeTypeHandleMetadata);
            }

            bulkRuntimeTypeHandleMetadata = new BulkRuntimeTypeHandleMetadata();
            var tableName   = Resolvers.Table(type);
            var keyProperty = Resolvers.KeyProperty(type, out var isIdentity);

            var columns       = new List <Tuple <string, Type> >();
            var propertyInfos = new List <PropertyInfo>();

            foreach (var typeProperty in Resolvers.Properties(type))
            {
                if (typeProperty == keyProperty)
                {
                    if (isIdentity)
                    {
                        bulkRuntimeTypeHandleMetadata.IdentityColumn = Resolvers.DataColumn(typeProperty);
                    }
                }
                if (typeProperty.PropertyInfo.GetSetMethod() != null)
                {
                    columns.Add(Resolvers.DataColumn(typeProperty));
                    propertyInfos.Add(typeProperty.PropertyInfo);
                }
            }

            if (outputIdentity.HasValue && outputIdentity.Value)
            {
                columns.Add(new Tuple <string, Type>("InternalId", typeof(int)));
                propertyInfos.Add(null);
            }

            bulkRuntimeTypeHandleMetadata.Columns       = columns.ToArray();
            bulkRuntimeTypeHandleMetadata.PropertyInfos = propertyInfos.ToArray();
            bulkRuntimeTypeHandleMetadata.Name          = tableName;

            BulkOperationsCache.TryAdd(type.TypeHandle, bulkRuntimeTypeHandleMetadata);

            return(bulkRuntimeTypeHandleMetadata);
        }
コード例 #7
0
        /// <summary>
        /// Builds the update set.
        /// </summary>
        /// <param name="bulkMetadata">The bulk metadata.</param>
        /// <returns></returns>
        private static string BuildUpdateSet(BulkRuntimeTypeHandleMetadata bulkMetadata)
        {
            var command         = new StringBuilder();
            var paramsSeparated = new List <string>();

            command.Append("UPDATE SET ");

            foreach (var column in bulkMetadata.Columns)
            {
                if ((bulkMetadata.IdentityColumn != null && column != bulkMetadata.IdentityColumn) || bulkMetadata.IdentityColumn == null)
                {
                    if (column.Item1 != "InternalId")
                    {
                        paramsSeparated.Add($"{bulkMetadata.Name}.[{column.Item1 }] = #{bulkMetadata.Name}.[{column.Item1 }]");
                    }
                }
            }

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

            return(command.ToString());
        }
コード例 #8
0
 /// <summary>
 /// Builds the join conditions for update or insert.
 /// </summary>
 /// <param name="bulkMetadata">The bulk metadata.</param>
 /// <returns></returns>
 private static string BuildJoinConditionsForUpdateOrInsert(BulkRuntimeTypeHandleMetadata bulkMetadata)
 {
     return($"ON {bulkMetadata.Name}.[{bulkMetadata.IdentityColumn.Item1}] = #{bulkMetadata.Name}.[{bulkMetadata.IdentityColumn.Item1}] ");
 }
コード例 #9
0
        /// <summary>
        /// Checks the temporary table query.
        /// </summary>
        /// <param name="connection">The connection.</param>
        /// <param name="transaction">The transaction.</param>
        /// <param name="bulkRuntimeTypeHandleMetadata">The bulk runtime type handle metadata.</param>
        /// <param name="outputIdentity">The output identity.</param>
        private static void CheckTemporaryTableQuery(IDbConnection connection, IDbTransaction transaction, BulkRuntimeTypeHandleMetadata bulkRuntimeTypeHandleMetadata, bool?outputIdentity = null)
        {
            if (!string.IsNullOrEmpty(bulkRuntimeTypeHandleMetadata.TempTableQuery))
            {
                return;
            }

            var internalCol = string.Empty;

            if (outputIdentity.HasValue && outputIdentity.Value)
            {
                internalCol = ", [InternalId] int";
            }

            var tempTableGetCreateQuery = $@"
                SELECT N'CREATE TABLE #{bulkRuntimeTypeHandleMetadata.Name}(' + Stuff((
	                SELECT N', [' + c.name + '] ' + CASE 
			                WHEN t.Name in ('varchar', 'nvarchar', 'char', 'binary', 'varbinary')
			                THEN IIF(c.max_length = '-1', CONVERT(nvarchar(10),t.Name) + '(max)', CONVERT(nvarchar(10),t.Name) + '(' + CONVERT(nvarchar(10),c.max_length) + ')')
			                WHEN t.Name in ('numeric', 'decimal')
			                THEN CONVERT(nvarchar(10),t.Name) + '(' + CONVERT(nvarchar(10),c.precision) + ', ' + CONVERT(nvarchar(10),c.scale) + ')'
			                ELSE t.Name
		                END	
	                FROM sys.columns c INNER JOIN sys.types t ON c.user_type_id = t.user_type_id
	                LEFT OUTER JOIN sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
	                LEFT OUTER JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
	                WHERE c.object_id = OBJECT_ID('{bulkRuntimeTypeHandleMetadata.Name}')	FOR XML PATH(''), TYPE).value('text()[1]','nvarchar(max)'),1,2,N'') + '{internalCol});'"    ;

            var result = connection.ExecuteScalar <string>(tempTableGetCreateQuery, transaction: transaction);

            bulkRuntimeTypeHandleMetadata.TempTableQuery = result;
        }
コード例 #10
0
        /// <summary>
        /// Loads a DataTable from a sequence of objects.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="table">The input table. The schema of the table must match that
        /// the type T.  If the table is null, a new table is created with a schema
        /// created from the public properties and fields of the type T.</param>
        /// <param name="source">The sequence of objects to load into the DataTable.</param>
        /// <param name="bulkRuntimeTypeHandleMetadata">The bulk runtime type handle metadata.</param>
        /// <param name="options">Specifies how values from the source sequence will be applied to
        /// existing rows in the table.</param>
        /// <param name="outputIdentityDic">The output identity dic.</param>
        /// <param name="identifierOnly">if set to <c>true</c> [identifier only].</param>
        /// <returns>
        /// A DataTable created from the source sequence.
        /// </returns>
        private static DataTable Shred <TEntity>(this DataTable table, IEnumerable <TEntity> source, BulkRuntimeTypeHandleMetadata bulkRuntimeTypeHandleMetadata, LoadOption?options, Dictionary <int, TEntity> outputIdentityDic = null, bool identifierOnly = false) where TEntity : class
        {
            var counter = 0;

            // Enumerate the source sequence and load the object values into rows.
            table.BeginLoadData();
            using (var e = source.GetEnumerator())
            {
                while (e.MoveNext())
                {
                    if (options != null)
                    {
                        table.LoadDataRow(ShredObject(bulkRuntimeTypeHandleMetadata, e.Current, counter, outputIdentityDic, identifierOnly), (LoadOption)options);
                    }
                    else
                    {
                        table.LoadDataRow(ShredObject(bulkRuntimeTypeHandleMetadata, e.Current, counter, outputIdentityDic, identifierOnly), true);
                    }
                    counter++;
                }
            }
            table.EndLoadData();

            // Return the table.
            return(table);
        }