diff --git a/Dapper/SqlMapper.Settings.cs b/Dapper/SqlMapper.Settings.cs index d425d44d..cc71238b 100644 --- a/Dapper/SqlMapper.Settings.cs +++ b/Dapper/SqlMapper.Settings.cs @@ -93,6 +93,12 @@ namespace Dapper /// operation if there are this many elements or more. Note that this feature requires SQL Server 2016 / compatibility level 130 (or above). /// public static int InListStringSplitCount { get; set; } = -1; + + /// + /// If set, pseudo-positional parameters (i.e. ?foo?) are passed using auto-generated incremental names, i.e. "1", "2", "3" + /// instead of the original name; for most scenarios, this is ignored since the name is redundant, but "snowflake" requires this. + /// + public static bool UseIncrementalPseudoPositionalParameterNames { get; set; } } } } diff --git a/Dapper/SqlMapper.cs b/Dapper/SqlMapper.cs index 2edee8c6..00add11e 100644 --- a/Dapper/SqlMapper.cs +++ b/Dapper/SqlMapper.cs @@ -1778,6 +1778,8 @@ namespace Dapper } HashSet consumed = new HashSet(StringComparer.Ordinal); bool firstMatch = true; + int index = 0; // use this to spoof names; in most pseudo-positional cases, the name is ignored, however: + // for "snowflake", the name needs to be incremental i.e. "1", "2", "3" cmd.CommandText = pseudoPositional.Replace(cmd.CommandText, match => { string key = match.Groups[1].Value; @@ -1793,6 +1795,10 @@ namespace Dapper cmd.Parameters.Clear(); // only clear if we are pretty positive that we've found this pattern successfully } // if found, return the anonymous token "?" + if (Settings.UseIncrementalPseudoPositionalParameterNames) + { + param.ParameterName = (++index).ToString(); + } cmd.Parameters.Add(param); parameters.Remove(key); consumed.Add(key); diff --git a/tests/Dapper.Tests/Dapper.Tests.csproj b/tests/Dapper.Tests/Dapper.Tests.csproj index 5f74e4b8..f8402fca 100644 --- a/tests/Dapper.Tests/Dapper.Tests.csproj +++ b/tests/Dapper.Tests/Dapper.Tests.csproj @@ -20,10 +20,9 @@ + - -