TableValueParameter Ignores any Custom TypeHandlers
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 18.4k
- Forks
- 3.7k
- Avg merge
- 5h 8m
- Merged PRs (30d)
- 1
Description
I have some custom classes that hides some logic but is basically only a simple .Net Type. Think Email, there you can create a EMail class, that validates the string so it's a valid email address, and it could extract the domain from the email address. But in the end it's still only a string that is stored down to the database.
By using a custom TypeHandler, it's easy to store and retrieve this Email class to a single column in the database. The issue is if I use the TableValueParameter function my Custom TypeHandler is "ignored".
I can create a DataTable with a DataColumn with the Type of my EMail class, but as soon as I try to execute my SQL statement with the SqlMapper.ICustomQueryParameter it fails since dapper can't convert the EMail class into a DbType. And since I already have a CustomTypeHandler specified for my EMail class it would be nice if it was extended to work with TableValueParameters to.
This is how my CustomTypeHandler looks today.
` public class FlightNumberTypeHandler : SqlMapper.TypeHandler<FlightNumber>
{
public override void SetValue(IDbDataParameter parameter, FlightNumber value)
{
parameter.DbType = DbType.String;
parameter.Value = value.ToString();
}
public override FlightNumber Parse(object value)
{
return FlightNumber.Create(value.ToString());
}
}`
By adding 2 abstract properties, one for the Value and one for the DbType it could be changed to look like this instead.
public class FlightNumberTypeHandler : SqlMapper.TypeHandler<FlightNumber>
{
public override DbType DbType => DbType.String;
public override object GetValue(FlightNumber item)
{
return item.ToString();
}
public override FlightNumber Parse(object value)
{
return FlightNumber.Create(value.ToString());
}
}
And the public void SetValue(IDbDataParameter parameter, FlightNumber value) method in the base class could use the newley abstract method/property to set the parameter, so there isn't any need to override that method if these are the only 2 things set in the method. And the logic that converts the DataTable to a TableValueParameter could also use the Custom TypeHandler to convert the FlightNumber type to a String.
Best Regards
Magnus
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 by tracing TableValueParameter conversion and how SqlMapper.TypeHandler currently sets values and DbType. Check the surrounding parameter-mapping code and existing tests, if present, to determine where custom handlers are bypassed. Done means a custom handler converts the value and database type for table-valued parameters without breaking existing handlers.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, sql
- Domain
- database
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100