Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Dapper/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ static Dapper.SqlMapper.SanitizeParameterValue(object? value) -> object!
static Dapper.SqlMapper.SetDbType(System.Data.IDataParameter! parameter, object! value) -> void
static Dapper.SqlMapper.Settings.ApplyNullValues.get -> bool
static Dapper.SqlMapper.Settings.ApplyNullValues.set -> void
static Dapper.SqlMapper.Settings.SupportLegacyParameterTokens.get -> bool
static Dapper.SqlMapper.Settings.SupportLegacyParameterTokens.set -> void
static Dapper.SqlMapper.Settings.CommandTimeout.get -> int?
static Dapper.SqlMapper.Settings.CommandTimeout.set -> void
static Dapper.SqlMapper.Settings.FetchSize.get -> long
Expand Down
7 changes: 7 additions & 0 deletions Dapper/SqlMapper.Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ public static long FetchSize
}
}

/// <summary>
/// Indicates whether single-character parameter tokens (<c>?</c> etc) will be detected and used where possible;
/// this feature is not recommended and will be disabled by default in future versions;
/// where possible, prefer named parameters (<c>@yourParam</c> etc) or Dapper's "pseudo-positional" parameters (<c>?yourParam? etc</c>).
/// </summary>
public static bool SupportLegacyParameterTokens { get; set; } = true;

private static long s_FetchSize = -1;
}
}
Expand Down
6 changes: 4 additions & 2 deletions Dapper/SqlMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2534,11 +2534,13 @@ private static bool IsValueTuple(Type? type) => (type?.IsValueType == true
throw new NotSupportedException("ValueTuple should not be used for parameters - the language-level names are not available to use as parameter names, and it adds unnecessary boxing");
}

bool filterParams = false;
if (removeUnused && identity.CommandType.GetValueOrDefault(CommandType.Text) == CommandType.Text)
bool filterParams = removeUnused && identity.CommandType.GetValueOrDefault(CommandType.Text) == CommandType.Text;

if (filterParams && Settings.SupportLegacyParameterTokens)
{
filterParams = !smellsLikeOleDb.IsMatch(identity.Sql);
}

var dm = new DynamicMethod("ParamInfo" + Guid.NewGuid().ToString(), null, new[] { typeof(IDbCommand), typeof(object) }, type, true);

var il = dm.GetILGenerator();
Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Note: to get the latest pre-release build, add ` -Pre` to the end of the command
(note: new PRs will not be merged until they add release note wording here)

- infer command text without any whitespace as stored-procedure (#1975 via @mgravell)
- add global `SupportLegacyParameterTokens` setting to enable or disable single-character parameter tokens (#1974 via @Giorgi)

### 2.1.4

Expand Down
35 changes: 35 additions & 0 deletions tests/Dapper.Tests/ParameterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1511,6 +1511,36 @@ public void Issue601_InternationalParameterNamesWork()
[FactLongRunning]
public void TestListExpansionPadding_Disabled() => TestListExpansionPadding(false);

[Theory]
[InlineData(true)]
[InlineData(false)]
public void OleDbParamFilterFails(bool legacyParameterToken)
{
SqlMapper.PurgeQueryCache();
var oldValue = SqlMapper.Settings.SupportLegacyParameterTokens;
try
{
SqlMapper.Settings.SupportLegacyParameterTokens = legacyParameterToken;

if (legacyParameterToken) // OLE DB parameter support enabled; can false-positive
{
Assert.Throws<NotSupportedException>(() => GetValue(connection));
}
else // OLE DB parameter support disabled; more reliable
{
Assert.Equal("this ? could be awkward", GetValue(connection));
}
}
finally
{
SqlMapper.Settings.SupportLegacyParameterTokens = oldValue;
}

static string GetValue(DbConnection connection)
=> connection.QuerySingle<string>("select 'this ? could be awkward'",
new TypeWithDodgyProperties());
}

private void TestListExpansionPadding(bool enabled)
{
bool oldVal = SqlMapper.Settings.PadListExpansions;
Expand Down Expand Up @@ -1706,5 +1736,10 @@ class HazNullableSqlDecimal
public int Id { get; set; }
public SqlDecimal? Value { get; set; }
}

class TypeWithDodgyProperties
{
public string Name => throw new NotSupportedException();
}
}
}