From 0a140ef0899acc3dadadb00942210cbd964f60c0 Mon Sep 17 00:00:00 2001 From: Joshua Rogers Date: Tue, 10 Jan 2023 12:39:01 -0800 Subject: [PATCH] Adds setting `ForceListExpansion` to provide a way to enable consistent handling of list parameters regardless of RDBMS (#1871) --- Dapper/SqlMapper.Settings.cs | 7 +++++++ Dapper/SqlMapper.cs | 2 +- Readme.md | 4 +++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Dapper/SqlMapper.Settings.cs b/Dapper/SqlMapper.Settings.cs index cc71238b2..8be05c92e 100644 --- a/Dapper/SqlMapper.Settings.cs +++ b/Dapper/SqlMapper.Settings.cs @@ -99,6 +99,13 @@ public static void SetDefaults() /// 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; } + + /// + /// If set, this causes Dapper to perform list expansion on any list provided as a query parameter, even if the RDBMS driver has + /// native list support. Enabling this will be less efficient than using native support, but provides for consistent list + /// handling regardless of underlying RDBMS. See https://github.com/DapperLib/Dapper/issues/1871. + /// + public static bool ForceListExpansion { get; set; } } } } diff --git a/Dapper/SqlMapper.cs b/Dapper/SqlMapper.cs index ee49c2abd..bbb738c01 100644 --- a/Dapper/SqlMapper.cs +++ b/Dapper/SqlMapper.cs @@ -2022,7 +2022,7 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj // initially we tried TVP, however it performs quite poorly. // keep in mind SQL support up to 2000 params easily in sp_executesql, needing more is rare - if (FeatureSupport.Get(command.Connection).Arrays) + if (FeatureSupport.Get(command.Connection).Arrays && !Settings.ForceListExpansion) { var arrayParm = command.CreateParameter(); arrayParm.Value = SanitizeParameterValue(value); diff --git a/Readme.md b/Readme.md index 1a6061b8c..57f1fb400 100644 --- a/Readme.md +++ b/Readme.md @@ -230,7 +230,7 @@ When an object that implements the `IDynamicParameters` interface passed into `E List Support ------------ -Dapper allows you to pass in `IEnumerable` and will automatically parameterize your query. +Dapper allows you to pass in `IEnumerable` and will automatically parameterize your query if your database driver does not natively support passing a list as a parameter. For example: @@ -244,6 +244,8 @@ Will be translated to: select * from (select 1 as Id union all select 2 union all select 3) as X where Id in (@Ids1, @Ids2, @Ids3)" // @Ids1 = 1 , @Ids2 = 2 , @Ids2 = 3 ``` +For database drivers that do support list parameters (at this time, Postgres and ClickHouse), list expansion is not performed since it is not required. However, automatic expansion can be used even if the driver does not require it by setting the global flag `SqlMapper.Settings.ForceListExpansion`. This is only needed when writing SQL that is intended for use by multiple databases, when trying to ensure consistent list handling and is disabled by default. + Literal replacements ------------ Dapper supports literal replacements for bool and numeric types.