/// <summary>
        /// Starts a data merge operation with the specified destination table name.
        /// </summary>
        /// <param name="session">The session to use for the merge.</param>
        /// <param name="destinationTable">Name of the destination table on the server.</param>
        /// <returns>
        /// A fluent <see langword="interface" /> to a <see cref="DataMerge " /> operation.
        /// </returns>
        public static IDataMerge MergeData(this IDataSession session, string destinationTable)
        {
            var definition = new DataMergeDefinition();
            definition.TargetTable = destinationTable;

            return MergeData(session, definition);
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a <see cref="DataMergeDefinition" /> from the specified <paramref name="importContext" />.
        /// </summary>
        /// <param name="importContext">The import context.</param>
        /// <returns>
        /// An instance of <see cref="DataMergeDefinition" />
        /// </returns>
        /// <exception cref="InvalidOperationException">Could not find matching field definition for data column</exception>
        protected virtual DataMergeDefinition CreateMergeDefinition(ImportProcessContext importContext)
        {
            var importDefinition = importContext.Definition;

            var mergeDefinition = new DataMergeDefinition();

            mergeDefinition.TargetTable   = importDefinition.TargetTable;
            mergeDefinition.IncludeInsert = importDefinition.CanInsert;
            mergeDefinition.IncludeUpdate = importDefinition.CanUpdate;

            // fluent builder
            var mergeMapping = new DataMergeMapping(mergeDefinition);

            // map included columns
            foreach (var fieldMapping in importContext.MappedFields)
            {
                var fieldDefinition = fieldMapping.Definition;
                var nativeType      = SqlTypeMapping.NativeType(fieldDefinition.DataType);

                mergeMapping
                .Column(fieldDefinition.Name)
                .Insert(fieldDefinition.CanInsert)
                .Update(fieldDefinition.CanUpdate)
                .Key(fieldDefinition.IsKey)
                .NativeType(nativeType);
            }

            return(mergeDefinition);
        }
        /// <summary>
        /// Builds the SQL for the temporary table used in the merge operation.
        /// </summary>
        /// <param name="mergeDefinition">The merge definition.</param>
        /// <returns></returns>
        public static string BuildTable(DataMergeDefinition mergeDefinition)
        {
            var builder = new StringBuilder();
            builder
                .Append("CREATE TABLE ")
                .Append(TableIdentifier(mergeDefinition.TemporaryTable))
                .AppendLine()
                .Append("(")
                .AppendLine();

            bool hasColumn = false;
            foreach (var mergeColumn in mergeDefinition.Columns.Where(c => !c.IsIgnored))
            {
                bool writeComma = hasColumn;

                builder
                    .AppendLineIf(",", v => writeComma)
                    .Append(' ', TabSize)
                    .Append(QuoteIdentifier(mergeColumn.SourceColumn))
                    .Append(" ")
                    .Append(mergeColumn.NativeType)
                    .Append(" NULL");

                hasColumn = true;
            }

            builder
                .AppendLine()
                .Append(")")
                .AppendLine();

            return builder.ToString();
        }
Esempio n. 4
0
        private IEnumerable <DataMergeOutputRow> Merge(DataMergeDefinition mergeDefinition, DataTable dataTable)
        {
            _logger.LogDebug("Executing batch merge to: '{table}'", mergeDefinition.TargetTable);

            var result = _dataSession
                         .MergeData(mergeDefinition)
                         .ExecuteOutput(dataTable)
                         .ToList();

            return(result);
        }
Esempio n. 5
0
        public void BuildMergeDataOutputTests()
        {
            var definition = new DataMergeDefinition();

            DataMergeDefinition.AutoMap <UserImport>(definition);
            definition.Columns.Should().NotBeNullOrEmpty();

            definition.IncludeOutput = true;
            definition.TargetTable   = "dbo.User";

            var column = definition.Columns.Find(c => c.SourceColumn == "EmailAddress");

            column.Should().NotBeNull();

            column.IsKey     = true;
            column.CanUpdate = false;

            var users = new List <UserImport>
            {
                new UserImport
                {
                    EmailAddress = "*****@*****.**",
                    DisplayName  = "Test User",
                    FirstName    = "Test",
                    LastName     = "User"
                },
                new UserImport
                {
                    EmailAddress = "*****@*****.**",
                    DisplayName  = "Blah User",
                    FirstName    = "Blah",
                    LastName     = "User"
                },
                new UserImport
                {
                    EmailAddress = $"random.{DateTime.Now.Ticks}@email.com",
                    DisplayName  = "Random User",
                    FirstName    = "Random",
                    LastName     = "User"
                }
            };

            var dataTable = users.ToDataTable();

            var sql = DataMergeGenerator.BuildMerge(definition, dataTable);

            sql.Should().NotBeNullOrEmpty();

            Output.WriteLine("MergeStatement:");
            Output.WriteLine(sql);
        }
Esempio n. 6
0
        private IEnumerable <DataMergeOutputRow> Merge(DataMergeDefinition mergeDefinition, DataTable dataTable, string connectionName)
        {
            Logger.Debug()
            .Message("Executing batch merge to: '{0}'", mergeDefinition.TargetTable)
            .Write();

            List <DataMergeOutputRow> result;

            using (var session = new DataSession(connectionName))
            {
                result = session
                         .MergeData(mergeDefinition)
                         .MergeOutput(dataTable)
                         .ToList();
            }
            return(result);
        }
Esempio n. 7
0
        private IEnumerable <DataMergeOutputRow> Merge(DataMergeDefinition mergeDefinition, DataTable dataTable, IDataConfiguration dataConfiguration)
        {
            Logger.Debug()
            .Message("Executing batch merge to: '{0}'", mergeDefinition.TargetTable)
            .Write();

            List <DataMergeOutputRow> result;

            using (var session = dataConfiguration.CreateSession())
            {
                result = session
                         .MergeData(mergeDefinition)
                         .ExecuteOutput(dataTable)
                         .ToList();
            }
            return(result);
        }
Esempio n. 8
0
        public void BuildMergeTests()
        {
            var definition = new DataMergeDefinition();

            DataMergeDefinition.AutoMap <UserImport>(definition);
            definition.Columns.Should().NotBeNullOrEmpty();

            definition.TargetTable = "dbo.User";

            var column = definition.Columns.Find(c => c.SourceColumn == "EmailAddress");

            column.Should().NotBeNull();

            column.IsKey     = true;
            column.CanUpdate = false;

            var sql = DataMergeGenerator.BuildMerge(definition);

            sql.Should().NotBeNullOrEmpty();

            Output.WriteLine("MergeStatement:");
            Output.WriteLine(sql);
        }
Esempio n. 9
0
        private DataMergeDefinition CreateDefinition(BatchJob batchJob)
        {
            var mergeDefinition = new DataMergeDefinition();

            mergeDefinition.TargetTable   = batchJob.TargetTable;
            mergeDefinition.IncludeInsert = batchJob.CanInsert;
            mergeDefinition.IncludeUpdate = batchJob.CanUpdate;

            // fluent builder
            var mergeMapping = new DataMergeMapping(mergeDefinition);

            // map included columns
            foreach (var fieldMapping in batchJob.Fields.Where(m => m.Index.HasValue || m.Default.HasValue))
            {
                mergeMapping
                .Column(fieldMapping.Name)
                .Insert(fieldMapping.CanInsert)
                .Update(fieldMapping.CanUpdate)
                .NativeType(fieldMapping.NativeType)
                .Key(fieldMapping.IsKey);
            }

            return(mergeDefinition);
        }
 /// <summary>
 /// Starts a data merge operation with the specified destination table name.
 /// </summary>
 /// <param name="session">The session to use for the merge.</param>
 /// <param name="mergeDefinition">The data merge definition.</param>
 /// <returns>
 /// A fluent <see langword="interface" /> to a <see cref="DataMerge " /> operation.
 /// </returns>
 public static IDataMerge MergeData(this IDataSession session, DataMergeDefinition mergeDefinition)
 {
     var dataMerge = new DataMerge(session, mergeDefinition);
     return dataMerge;
 }
Esempio n. 11
0
        private IEnumerable<DataMergeOutputRow> Merge(DataMergeDefinition mergeDefinition, DataTable dataTable, string connectionName)
        {
            Logger.Debug()
                .Message("Executing batch merge to: '{0}'", mergeDefinition.TargetTable)
                .Write();

            List<DataMergeOutputRow> result;
            using (var session = new DataSession(connectionName))
            {
                result = session
                    .MergeData(mergeDefinition)
                    .MergeOutput(dataTable)
                    .ToList();
            }
            return result;
        }
        /// <summary>
        /// Builds the SQL merge statement for the merge operation.
        /// </summary>
        /// <param name="mergeDefinition">The merge definition.</param>
        /// <returns></returns>
        public static string BuildMerge(DataMergeDefinition mergeDefinition)
        {
            var mergeColumns = mergeDefinition.Columns
                .Where(c => !c.IsIgnored)
                .ToList();

            var builder = new StringBuilder();

            if (mergeDefinition.IdentityInsert && mergeDefinition.IncludeInsert)
            {
                builder
                    .Append("SET IDENTITY_INSERT ")
                    .Append(TableIdentifier(mergeDefinition.TargetTable))
                    .AppendLine(" ON;")
                    .AppendLine();
            }


            builder
                .Append("MERGE INTO ")
                .Append(TableIdentifier(mergeDefinition.TargetTable))
                .Append(" AS t")
                .AppendLine()
                .AppendLine("USING")
                .AppendLine("(")
                .Append(' ', TabSize)
                .AppendLine("SELECT");

            bool hasColumn = false;
            foreach (var mergeColumn in mergeColumns)
            {
                bool writeComma = hasColumn;

                builder
                    .AppendLineIf(",", v => writeComma)
                    .Append(' ', TabSize * 2)
                    .Append(QuoteIdentifier(mergeColumn.SourceColumn));

                hasColumn = true;
            }

            builder
                .AppendLine()
                .Append(' ', TabSize)
                .Append("FROM ")
                .Append(TableIdentifier(mergeDefinition.TemporaryTable))
                .AppendLine()
                .AppendLine(")")
                .AppendLine("AS s")
                .AppendLine("ON")
                .AppendLine("(");

            hasColumn = false;
            foreach (var mergeColumn in mergeColumns.Where(c => c.IsKey))
            {
                bool writeComma = hasColumn;
                builder
                    .AppendLineIf(" AND ", v => writeComma)
                    .Append(' ', TabSize)
                    .Append("t.")
                    .Append(QuoteIdentifier(mergeColumn.TargetColumn))
                    .Append(" = s.")
                    .Append(QuoteIdentifier(mergeColumn.SourceColumn));

                hasColumn = true;
            }

            builder
                .AppendLine()
                .Append(")")
                .AppendLine();

            // Insert
            AppendInsert(mergeDefinition, builder);

            // Update
            AppendUpdate(mergeDefinition, builder);

            // Delete
            AppendDelete(mergeDefinition, builder);

            // Output
            AppendOutput(mergeDefinition, builder);

            // merge must end with ;
            builder.Append(";");

            if (mergeDefinition.IdentityInsert && mergeDefinition.IncludeInsert)
            {
                builder
                    .Append("SET IDENTITY_INSERT ")
                    .Append(TableIdentifier(mergeDefinition.TargetTable))
                    .AppendLine(" OFF;")
                    .AppendLine();
            }

            return builder.ToString();
        }
        private static void AppendInsert(DataMergeDefinition mergeDefinition, StringBuilder builder)
        {
            if (!mergeDefinition.IncludeInsert)
                return;

            var mergeColumns = mergeDefinition.Columns
                .Where(c => !c.IsIgnored && c.CanInsert)
                .ToList();

            builder
                .AppendLine("WHEN NOT MATCHED BY TARGET THEN ")
                .Append(' ', TabSize)
                .AppendLine("INSERT")
                .Append(' ', TabSize)
                .AppendLine("(");

            bool hasColumn = false;
            foreach (var mergeColumn in mergeColumns)
            {
                bool writeComma = hasColumn;
                builder
                    .AppendLineIf(",", v => writeComma)
                    .Append(' ', TabSize * 2)
                    .Append(QuoteIdentifier(mergeColumn.TargetColumn));

                hasColumn = true;
            }
            builder.AppendLine();

            builder
                .Append(' ', TabSize)
                .AppendLine(")")
                .Append(' ', TabSize)
                .AppendLine("VALUES")
                .Append(' ', TabSize)
                .AppendLine("(");

            hasColumn = false;
            foreach (var mergeColumn in mergeColumns)
            {
                bool writeComma = hasColumn;
                builder
                    .AppendLineIf(",", v => writeComma)
                    .Append(' ', TabSize * 2)
                    .Append("s.")
                    .Append(QuoteIdentifier(mergeColumn.SourceColumn));

                hasColumn = true;
            }
            builder.AppendLine();

            builder
                .Append(' ', TabSize)
                .AppendLine(")");
        }
        private static void AppendUpdate(DataMergeDefinition mergeDefinition, StringBuilder builder)
        {
            if (!mergeDefinition.IncludeUpdate)
                return;

            var mergeColumns = mergeDefinition.Columns
                .Where(c => !c.IsIgnored && c.CanUpdate)
                .ToList();

            builder
                .AppendLine("WHEN MATCHED THEN ")
                .Append(' ', TabSize)
                .AppendLine("UPDATE SET");

            bool hasColumn = false;
            foreach (var mergeColumn in mergeColumns)
            {
                bool writeComma = hasColumn;
                builder
                    .AppendLineIf(",", v => writeComma)
                    .Append(' ', TabSize * 2)
                    .Append("t.")
                    .Append(QuoteIdentifier(mergeColumn.TargetColumn))
                    .Append(" = s.")
                    .Append(QuoteIdentifier(mergeColumn.SourceColumn));

                hasColumn = true;
            }
            builder.AppendLine();
        }
        private static void AppendDelete(DataMergeDefinition mergeDefinition, StringBuilder builder)
        {
            if (!mergeDefinition.IncludeDelete)
                return;

            builder
                .AppendLine("WHEN NOT MATCHED BY SOURCE THEN ")
                .Append(' ', TabSize)
                .AppendLine("DELETE");
        }
Esempio n. 16
0
        private DataMergeDefinition CreateDefinition(BatchJob batchJob)
        {
            var mergeDefinition = new DataMergeDefinition();
            mergeDefinition.TargetTable = batchJob.TargetTable;
            mergeDefinition.IncludeInsert = batchJob.CanInsert;
            mergeDefinition.IncludeUpdate = batchJob.CanUpdate;

            // fluent builder
            var mergeMapping = new DataMergeMapping(mergeDefinition);

            // map included columns
            foreach (var fieldMapping in batchJob.SourceMapping.Where(c => c.IsIncluded))
            {
                mergeMapping
                    .Column(fieldMapping.Name)
                    .Insert(fieldMapping.CanInsert)
                    .Update(fieldMapping.CanUpdate)
                    .NativeType(fieldMapping.NativeType)
                    .Key(fieldMapping.IsKey);
            }

            return mergeDefinition;
        }
        private static void AppendOutput(DataMergeDefinition mergeDefinition, StringBuilder builder)
        {
            if (!mergeDefinition.IncludeOutput)
                return;

            var mergeColumns = mergeDefinition.Columns
                .Where(c => !c.IsIgnored)
                .ToList();

            builder
                .AppendLine("OUTPUT")
                .Append(' ', TabSize)
                .Append("$action as [Action]");

            foreach (var mergeColumn in mergeColumns)
            {
                builder
                    .AppendLine(",")
                    .Append(' ', TabSize)
                    .Append("DELETED.")
                    .Append(QuoteIdentifier(mergeColumn.SourceColumn))
                    .Append(" as [")
                    .Append(OriginalPrefix)
                    .Append(ParseIdentifier(mergeColumn.SourceColumn))
                    .Append("],")
                    .AppendLine();

                builder
                    .Append(' ', TabSize)
                    .Append("INSERTED.")
                    .Append(QuoteIdentifier(mergeColumn.SourceColumn))
                    .Append(" as [")
                    .Append(CurrentPrefix)
                    .Append(ParseIdentifier(mergeColumn.SourceColumn))
                    .Append("]");
            }

        }