in src/SqlAsyncCollector.cs [528:557]
public static string GetMergeQuery(IList<PrimaryKey> primaryKeys, SqlObject table, IEnumerable<string> bracketedColumnNamesFromItem)
{
IList<string> bracketedPrimaryKeys = primaryKeys.Select(p => p.Name.AsBracketQuotedString()).ToList();
// Generate the ON part of the merge query (compares new data against existing data)
var primaryKeyMatchingQuery = new StringBuilder($"ExistingData.{bracketedPrimaryKeys[0]} = NewData.{bracketedPrimaryKeys[0]}");
foreach (string primaryKey in bracketedPrimaryKeys.Skip(1))
{
primaryKeyMatchingQuery.Append($" AND ExistingData.{primaryKey} = NewData.{primaryKey}");
}
// Generate the UPDATE part of the merge query (all columns that should be updated)
var columnMatchingQueryBuilder = new StringBuilder();
foreach (string column in bracketedColumnNamesFromItem)
{
columnMatchingQueryBuilder.Append($" ExistingData.{column} = NewData.{column},");
}
string columnMatchingQuery = columnMatchingQueryBuilder.ToString().TrimEnd(',');
return $@"
MERGE INTO {table.BracketQuotedFullName} WITH (HOLDLOCK)
AS ExistingData
USING {CteName}
AS NewData
ON
{primaryKeyMatchingQuery}
WHEN MATCHED THEN
UPDATE SET {columnMatchingQuery}
WHEN NOT MATCHED THEN
INSERT ({string.Join(",", bracketedColumnNamesFromItem)}) VALUES ({string.Join(",", bracketedColumnNamesFromItem)})";
}