public static DwhTableBuilder[] RemoveExistingRows(this DwhTableBuilder[] builders, Action <RemoveExistingRowsBuilder> customizer) { foreach (var tableBuilder in builders) { var tempBuilder = new RemoveExistingRowsBuilder(tableBuilder); customizer.Invoke(tempBuilder); if (tempBuilder.MatchColumns == null) { throw new NotSupportedException("you must specify the key columns of " + nameof(RemoveExistingRows) + " for table " + tableBuilder.ResilientTable.TableName); } if (tempBuilder.CompareValueColumns == null && tempBuilder.MatchButDifferentAction != null) { throw new NotSupportedException("you must specify the comparable value columns of " + nameof(RemoveExistingRows) + " for table " + tableBuilder.ResilientTable.TableName + " if you specify the " + nameof(tempBuilder.MatchButDifferentAction)); } tableBuilder.AddMutatorCreator(_ => CreateRemoveExistingIdenticalRowsMutators(tempBuilder)); } return(builders); }
private static IEnumerable <IMutator> CreateRemoveExistingIdenticalRowsMutators(RemoveExistingRowsBuilder builder) { var finalValueColumns = builder.CompareValueColumns? .Where(x => !builder.MatchColumns.Contains(x) && !x.IsPrimaryKey) .ToArray(); if (finalValueColumns?.Length > 0) { var equalityComparer = new ColumnBasedRowEqualityComparer() { Columns = finalValueColumns.Select(x => x.Name).ToArray(), }; if (builder.MatchColumns.Length == 1) { yield return(new BatchedCompareWithRowMutator(builder.TableBuilder.ResilientTable.Scope.Context) { Name = nameof(RemoveExistingRows), RowFilter = row => row.HasValue(builder.MatchColumns[0].Name), EqualityComparer = equalityComparer, LookupBuilder = new FilteredRowLookupBuilder() { ProcessCreator = filterRows => new CustomSqlAdoNetDbReader(builder.TableBuilder.ResilientTable.Scope.Context) { Name = "ExistingRowsReader", ConnectionString = builder.TableBuilder.ResilientTable.Scope.ConnectionString, MainTableName = builder.TableBuilder.Table.SchemaAndName, Sql = "SELECT " + builder.MatchColumns[0].NameEscaped(builder.TableBuilder.DwhBuilder.ConnectionString) + "," + string.Join(", ", finalValueColumns.Select(c => c.NameEscaped(builder.TableBuilder.DwhBuilder.ConnectionString))) + " FROM " + builder.TableBuilder.Table.EscapedName(builder.TableBuilder.DwhBuilder.ConnectionString) + " WHERE " + builder.MatchColumns[0].NameEscaped(builder.TableBuilder.DwhBuilder.ConnectionString) + " IN (@keyList)", InlineArrayParameters = true, Parameters = new Dictionary <string, object>() { ["keyList"] = filterRows .Select(row => row.FormatToString(builder.MatchColumns[0].Name)) .Distinct() .ToArray(), }, }, KeyGenerator = row => row.GenerateKey(builder.MatchColumns[0].Name), }, RowKeyGenerator = row => row.GenerateKey(builder.MatchColumns[0].Name), MatchAndEqualsAction = new MatchAction(MatchMode.Remove), MatchButDifferentAction = builder.MatchButDifferentAction, BatchSize = 2000, }); } else { yield return(new CompareWithRowMutator(builder.TableBuilder.ResilientTable.Scope.Context) { Name = nameof(RemoveExistingRows), EqualityComparer = equalityComparer, LookupBuilder = new RowLookupBuilder() { Process = new CustomSqlAdoNetDbReader(builder.TableBuilder.ResilientTable.Scope.Context) { Name = "ExistingRowsReader", ConnectionString = builder.TableBuilder.DwhBuilder.ConnectionString, MainTableName = builder.TableBuilder.Table.SchemaAndName, Sql = "SELECT " + string.Join(",", builder.MatchColumns.Concat(finalValueColumns).Select(c => c.NameEscaped(builder.TableBuilder.DwhBuilder.ConnectionString))) + " FROM " + builder.TableBuilder.Table.EscapedName(builder.TableBuilder.DwhBuilder.ConnectionString), }, KeyGenerator = row => row.GenerateKey(builder.MatchColumnNames), }, RowKeyGenerator = row => row.GenerateKey(builder.MatchColumnNames), MatchAndEqualsAction = new MatchAction(MatchMode.Remove), MatchButDifferentAction = builder.MatchButDifferentAction, }); } } else if (builder.MatchColumns.Length == 1) { yield return(new BatchedKeyTestMutator(builder.TableBuilder.ResilientTable.Scope.Context) { Name = nameof(RemoveExistingRows), RowFilter = row => row.HasValue(builder.MatchColumns[0].Name), LookupBuilder = new FilteredRowLookupBuilder() { ProcessCreator = filterRows => new CustomSqlAdoNetDbReader(builder.TableBuilder.ResilientTable.Scope.Context) { Name = "ExistingRowsReader", ConnectionString = builder.TableBuilder.ResilientTable.Scope.ConnectionString, MainTableName = builder.TableBuilder.Table.SchemaAndName, Sql = "SELECT " + builder.MatchColumns[0].NameEscaped(builder.TableBuilder.DwhBuilder.ConnectionString) + " FROM " + builder.TableBuilder.Table.EscapedName(builder.TableBuilder.DwhBuilder.ConnectionString) + " WHERE " + builder.MatchColumns[0].NameEscaped(builder.TableBuilder.DwhBuilder.ConnectionString) + " IN (@keyList)", InlineArrayParameters = true, Parameters = new Dictionary <string, object>() { ["keyList"] = filterRows .Select(row => row.FormatToString(builder.MatchColumns[0].Name)) .Distinct() .ToArray(), }, }, KeyGenerator = row => row.GenerateKey(builder.MatchColumns[0].Name), }, RowKeyGenerator = row => row.GenerateKey(builder.MatchColumns[0].Name), MatchAction = new MatchAction(MatchMode.Remove), BatchSize = 2000, }); } else { yield return(new KeyTestMutator(builder.TableBuilder.ResilientTable.Scope.Context) { Name = nameof(RemoveExistingRows), LookupBuilder = new RowLookupBuilder() { Process = new CustomSqlAdoNetDbReader(builder.TableBuilder.ResilientTable.Scope.Context) { Name = "ExistingRowsReader", ConnectionString = builder.TableBuilder.DwhBuilder.ConnectionString, MainTableName = builder.TableBuilder.Table.SchemaAndName, Sql = "SELECT " + string.Join(",", builder.MatchColumns.Select(c => c.NameEscaped(builder.TableBuilder.DwhBuilder.ConnectionString))) + " FROM " + builder.TableBuilder.Table.EscapedName(builder.TableBuilder.DwhBuilder.ConnectionString), }, KeyGenerator = row => row.GenerateKey(builder.MatchColumnNames), }, RowKeyGenerator = row => row.GenerateKey(builder.MatchColumnNames), MatchActionContainsMatch = false, MatchAction = new MatchAction(MatchMode.Remove), }); } }