DapperLib / DapperLib/Dapper

TableValueParameter Ignores any Custom TypeHandlers

Open
#1,201 3 comments 0 reactions 0 assignees View on GitHub

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.