TypeHandlers not called for parameters extracted from list expansion
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 18.4k
- Forks
- 3.7k
- Avg merge
- 5h 8m
- Merged PRs (30d)
- 1
Description
I've noticed that types with a TypeHandler registered will not have that handler executed if the type is part of a collection that Dapper expands. Here's a test to reproduce this:
private readonly struct IdentityType
{
private readonly int _value;
public IdentityType(int value)
{
_value = value;
}
public int CompareTo(IdentityType other) => _value.CompareTo(other._value);
public override int GetHashCode() => _value;
public override string ToString() => _value.ToString();
public static explicit operator int(IdentityType d) => d._value;
public static explicit operator IdentityType(int d) => new(d);
}
private class IdentityTypeHandler : SqlMapper.TypeHandler<IdentityType>
{
public override IdentityType Parse(object value) => new((int)value);
public override void SetValue(IDbDataParameter parameter, IdentityType value)
{
parameter.DbType = DbType.Int32;
parameter.Value = (int)value;
}
}
[Fact]
public void Potato()
{
SqlMapper.AddTypeHandler(new IdentityTypeHandler());
var identityList = Enumerable.Range(1, 5)
.Select(i => new IdentityType(i))
.ToList();
var param = new { firstItem = identityList[0], allItems = identityList };
var result = connection.Query<int?>("SELECT * FROM (VALUES(1)) AS t(Id) WHERE @firstItem IN @allItems;", param)
.SingleOrDefault();
Assert.Equal(1, result);
}
I'm not familiar with the code here, but a bit of investigating led me to this line where the type handler would be fetched but not used. I managed to get my test to pass by persisting the handler and using it if it was set; but due to the other branches based on specific types (isString and isDbString), I'm not sure what the correct behaviour should be.. otherwise this would be a PR :D
Forgive me if this is intended and/or there's a different way to do it. I've searched around and couldn't find any information about this.
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.cs around line 2026 and reproduce the supplied Fact with the registered IdentityType TypeHandler and expanded collection parameter. Trace the existing handler, isString, and isDbString branches, then add a regression test showing the handler is used for expanded parameters without breaking the other cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, sql
- Domain
- backend, database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100