SqlMapper.Settings.cs: New option "StrictBinding"
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 18.4k
- Forks
- 3.7k
- Avg merge
- 5h 8m
- Merged PRs (30d)
- 1
Description
I would like to see a new option bool StrictBinding or similar in SqlMapper.Settings.cs that solves the following issues when set to true:
Issue 1: Null assignments to non-nullable (value) types
Currently, the following applies:
int i = connection.ExecuteScalar<int>("select cast(null as int)");
Assert.Equal(0, i);
which is not the behavior I was hoping for - I would have liked that Dapper slaps an exception in my face, saying "Are you OK? You are attempting to assign a null value to an Int32!" Or less prosa:
Action a = () => connection.ExecuteScalar<int>("select cast(null as int)");
Assert.ThrowsAny<Exception>(a);
Reason: I made a mistake, my data type in code does not match the data type returned by my query and I should have used one of the following options instead:
int? i = connection.ExecuteScalar<int?>("select cast(null as int)");
Assert.False(i.HasValue);
or
int i = connection.ExecuteScalar<int?>("select cast(null as int)") ?? 0;
Assert.Equal(0, i);
Issue 2: Narrowing casts (e.g. Int64 -> Int32)
Currently, the following applies:
int i = connection.ExecuteScalar<int>("select cast(123 as bigint)");
Assert.Equal(123, i);
which is cool at first glance (why not casting it as it fits into the range) but no, again, I prefer Dapper would slap me an exception in my face, saying "Are you OK? You are attempting to assign an Int64 value to an Int32!" Or less prosa:
Action a = () => connection.ExecuteScalar<int>("select cast(123 as bigint)");
Assert.ThrowsAny<Exception>(a);
Reason: I made a mistake, it is not safe to cast an Int64 into an Int32, that could be a sleeping bug that strikes when my code is long in production, e.g. when the record id exceeds Int32.MaxValue. Again my data type in code does not match the data type returned by my query and I should have used one of the following options instead:
long i = connection.ExecuteScalar<long>("select cast(123 as bigint)");
Assert.Equal(123L, i);
or
int i = (int)connection.ExecuteScalar<long>("select cast(123 as bigint)");
Assert.Equal(123, i);
What do you think?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in SqlMapper.Settings.cs and trace the ExecuteScalar conversion path used by the examples. Determine how StrictBinding should govern null assignments and narrowing casts, then add coverage for both cases and verify that permissive behavior remains unchanged when the option is not enabled.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, sql
- Domain
- backend, databases
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100