diff --git a/Dapper/CommandDefinition.cs b/Dapper/CommandDefinition.cs index 1820d86f4..f7132ed52 100644 --- a/Dapper/CommandDefinition.cs +++ b/Dapper/CommandDefinition.cs @@ -2,6 +2,7 @@ using System.Data; using System.Reflection; using System.Reflection.Emit; +using System.Text.RegularExpressions; using System.Threading; namespace Dapper @@ -103,14 +104,14 @@ public CommandDefinition(string commandText, object? parameters = null, IDbTrans static CommandType InferCommandType(string sql) { - if (sql is null || sql.IndexOfAny(WhitespaceChars) >= 0) return System.Data.CommandType.Text; + if (sql is null || WhitespaceChars.IsMatch(sql)) return System.Data.CommandType.Text; return System.Data.CommandType.StoredProcedure; } } - // if the sql contains any whitespace character (space/tab/cr/lf): interpret as ad-hoc; but "SomeName" should be treated as a stored-proc + // if the sql contains any whitespace character (space/tab/cr/lf/etc - via unicode): interpret as ad-hoc; but "SomeName" should be treated as a stored-proc // (note TableDirect would need to be specified explicitly, but in reality providers don't usually support TableDirect anyway) - private static readonly char[] WhitespaceChars = new char[] { ' ', '\t', '\r', '\n' }; + private static readonly Regex WhitespaceChars = new(@"\s", RegexOptions.Compiled); private CommandDefinition(object? parameters) : this() { diff --git a/Readme.md b/Readme.md index 218c1ed52..d2cd09d3a 100644 --- a/Readme.md +++ b/Readme.md @@ -21,6 +21,8 @@ MyGet Pre-release feed: https://www.myget.org/gallery/dapper | [Dapper.StrongName](https://www.nuget.org/packages/Dapper.StrongName/) | [![Dapper.StrongName](https://img.shields.io/nuget/v/Dapper.StrongName.svg)](https://www.nuget.org/packages/Dapper.StrongName/) | [![Dapper.StrongName](https://img.shields.io/nuget/vpre/Dapper.StrongName.svg)](https://www.nuget.org/packages/Dapper.StrongName/) | [![Dapper.StrongName](https://img.shields.io/nuget/dt/Dapper.StrongName.svg)](https://www.nuget.org/packages/Dapper.StrongName/) | [![Dapper.StrongName MyGet](https://img.shields.io/myget/dapper/vpre/Dapper.StrongName.svg)](https://www.myget.org/feed/dapper/package/nuget/Dapper.StrongName) | Package Purposes: +* Dapper + * The core library * Dapper.EntityFramework * Extension handlers for EntityFramework * Dapper.EntityFramework.StrongName @@ -29,24 +31,44 @@ Package Purposes: * Micro-ORM implemented on Dapper, provides CRUD helpers * Dapper.SqlBuilder * Component for building SQL queries dynamically and composably -* Dapper.StrongName - * High-performance micro-ORM supporting MySQL, Sqlite, SqlICE, and Firebird + +Sponsors +-------- + +Dapper was originally developed for and by Stack Overflow, but is F/OSS. Sponsorship is welcome and invited - see the sponsor link at the top of the page. +A huge thanks to everyone (individuals or organisations) who have sponsored Dapper, but a massive thanks in particular to: + +- [AWS](https://github.com/aws) who sponsored Dapper from Oct 2023 via the [.NET on AWS Open Source Software Fund](https://github.com/aws/dotnet-foss) Features -------- -Dapper is a [NuGet library](https://www.nuget.org/packages/Dapper) that you can add in to your project that will extend your `IDbConnection` interface. +Dapper is a [NuGet library](https://www.nuget.org/packages/Dapper) that you can add in to your project that will enhance your ADO.NET connections via +extension methods on your `DbConnection` instance. This provides a simple and efficient API for invoking SQL, with support for both synchronous and +asynchronous data access, and allows bother buffered and non-buffered queries. -It provides 3 helpers: +It provides multiple helpers, but the key APIs are: -Execute a query and map the results to a strongly typed List ------------------------------------------------------------- +``` csharp +// insert/update/delete etc +var count = connection.Execute(sql [, args]); -```csharp -public static IEnumerable Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) +// multi-row query +IEnumerable rows = connection.Query(sql [, args]); + +// single-row query ({Single|First}[OrDefault]) +T row = connection.QuerySingle(sql [, args]); ``` -Example usage: -```csharp +where `args` can be (among other things): + +- a simple POCO (including anonyomous types) for named parameters +- a `Dictionary` +- a `DynamicParameters` instance + +Execute a query and map it to a list of typed objects +------------------------------------------------------- + +``` csharp public class Dog { public int? Age { get; set; } @@ -68,9 +90,6 @@ Assert.Equal(guid, dog.First().Id); Execute a query and map it to a list of dynamic objects ------------------------------------------------------- -```csharp -public static IEnumerable Query (this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) -``` This method will execute SQL and return a dynamic list. Example usage: @@ -87,10 +106,6 @@ Assert.Equal(4, (int)rows[1].B); Execute a Command that returns no results ----------------------------------------- -```csharp -public static int Execute(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) -``` - Example usage: ```csharp diff --git a/docs/index.md b/docs/index.md index 992753923..e05950d63 100644 --- a/docs/index.md +++ b/docs/index.md @@ -20,13 +20,20 @@ Note: to get the latest pre-release build, add ` -Pre` to the end of the command ## Release Notes -### unreleased +**RELEASE NOTE TRACKING HAS MOVED TO GITHUB** + +See: https://github.com/DapperLib/Dapper/releases + +Archive only (no new entries): + +### 2.1.11 (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) - revert `$` addition for legacy parameter tokens (#1979 via @mgravell) +- change NRT annotation on `GetConstructorParameter` (#1980 via @mgravell, fixes #1969) ### 2.1.4 diff --git a/tests/Dapper.Tests/ProcedureTests.cs b/tests/Dapper.Tests/ProcedureTests.cs index 9d76f44b9..9cc71f474 100644 --- a/tests/Dapper.Tests/ProcedureTests.cs +++ b/tests/Dapper.Tests/ProcedureTests.cs @@ -302,5 +302,20 @@ select 1 as Num Assert.Empty(result); } + + [Theory] + [InlineData(" ")] + [InlineData("\u00A0")] // nbsp + [InlineData("\u202F")] // narrow nbsp + [InlineData("\u2000")] // n quad + [InlineData("\t")] + [InlineData("\r")] + [InlineData("\n")] + public async Task Issue1986_AutoProc_Whitespace(string space) + { + var sql = "select!42".Replace("!", space); + var result = await connection.QuerySingleAsync(sql); + Assert.Equal(42, result); + } } }