Dapper icon indicating copy to clipboard operation
Dapper copied to clipboard

TypeHandler Override -> SetValue not being called.

Open dredgy opened this issue 3 years ago • 4 comments

I have posted this on StackOverflow but I think it might be a bug, unless I'm missing something super simple.

Am trying to add a custom type handler for an F# Union Type. ParseValue works fine but SetValue does not seem to get called at all.

type PrimaryKey<'x> =
    | Id of int
    | EmptyPrimaryKey

..

type PrimaryKeyHandler<'X>() =
    inherit SqlMapper.TypeHandler<PrimaryKey<'X>>()

    override _.SetValue(param, value) =
        let valueOrNull =
            match value with
            | Id x -> box x
            | EmptyPrimaryKey -> null

        param.DbType <- DbType.Int32 (* Put in as a test , doesn't seem to do anything*)
        param.Value <- valueOrNull

    override _.Parse value =
        if isNull value || value = box DBNull.Value
        then EmptyPrimaryKey
        else Id (value :?> int)

Anything obvious jump out here?

dredgy avatar Sep 30 '22 13:09 dredgy

Does it not get called when there is a value present or when it is null (ie the result in the answer from the db is null)? I have a solution open for a null handler (they are ignored totally at the moment).

jonnymuir avatar May 20 '23 16:05 jonnymuir

Very likely the value was null. I can’t remember if I tested with a value or not, seems like something I’d do.

From what I recall, putting a breakpoint in the function indicated that it was simply not being called at all.

I will double check and get back to you

dredgy avatar May 21 '23 00:05 dredgy

If you need the handler to be called on a null I have a pull request for a solution on the following issue which may be of use to you https://github.com/DapperLib/Dapper/issues/1754

Of course your problem maybe something else completely :D or you might not need the handler to react, you might just be looking for the reason why it wasn’t called.

Good luck - let us know how you get on.

jonnymuir avatar May 21 '23 06:05 jonnymuir

When I did my initial development, I was using Dapper.Fsharp on top so it was a little hard to diagnose. I've done a few experiments this week using just plain dapper.

As far as I can tell, the SetValue override does not ever get called when using the PrimaryKey type as defined above - regardless of whether it is empty or has a value. The TypeHandler is properly registered, and the .Parse override does work. When trying to pass a PrimaryKey type to a query, it fails with:

The member param1 of type Project.Types+PrimaryKey`1 ... cannot be used as a parameter value

dredgy avatar Jun 09 '23 04:06 dredgy