protected virtual string MergeFromStagingSql() { string whenNotMatchedStatement = $@"WHEN NOT MATCHED BY TARGET THEN INSERT ({string.Join(", ", PropertiesToInsert.Select(i => i.SqlServer().ColumnName))}) VALUES ({string.Join(", ", PropertiesToInsert.Select(i => $"S.{i.SqlServer().ColumnName}"))})"; string whenMatchedStatement = PropertiesToUpdate.Count == 0 ? "" : $@"WHEN MATCHED THEN UPDATE SET {string.Join(", ", PropertiesToUpdate.Select(i => $"T.{i.SqlServer().ColumnName} = S.{i.SqlServer().ColumnName}"))}"; return($@"MERGE {SqlTargetTable} WITH (HOLDLOCK) AS T USING {SqlStagingTableName} AS S ON {string.Join(" AND ", PropertiesForPivot.Select(i => CreateEqualityConditionSql("T", "S", i)))} {whenNotMatchedStatement} {whenMatchedStatement} OUTPUT INSERTED.*, S.{TempColumnNumOrderName} INTO {SqlOutputStagingTableName};"); }
=> $@"sp_executesql N'set nocount on; select * from {SqlOutputStagingTableName} order by {TempColumnNumOrderName}';"; //the sp_execute is to prevent EF core to wrap the query into another subquery that will involve a different sorting depending in the situtation (not too proud of this solution, but I really didn't find better) protected virtual string GetOutputStagingForComputedColumnsSql() => $@"sp_executesql N'set nocount on; select T.* from {SqlStagingTableName} as S left join {SqlTargetTable} as T on {string.Join(" AND ", PropertiesForPivot.Select(i => CreateEqualityConditionSql("T", "S", i)))} order by S.{TempColumnNumOrderName}';";