Dapper icon indicating copy to clipboard operation
Dapper copied to clipboard

Dapper custom TypeHandler SetValue not being called?

Open RufusJWB opened this issue 10 years ago • 6 comments

I have exactly the same problem as it is described here: http://stackoverflow.com/questions/28727962/dapper-custom-typehandler-setvalue-not-being-called

Update: There is a second thread with the same problem: http://stackoverflow.com/questions/25568657/dapper-typehandler-setvalue-not-being-called?rq=1

RufusJWB avatar Jun 11 '15 08:06 RufusJWB

I have the same problem, and it looks to me like a bug.

Also, I think this is a duplicate of the issue https://github.com/StackExchange/dapper-dot-net/issues/206 The solution proposed in PR https://github.com/StackExchange/dapper-dot-net/pull/177 works for me.

I wonder if there are any issues with the solution in PR which are getting in the way of merging it in (apart from code conflicts which need to be resolved)

kartofeell avatar Aug 25 '15 18:08 kartofeell

+1

drusellers avatar Sep 18 '15 21:09 drusellers

+1

NimaAra avatar Sep 19 '16 21:09 NimaAra

Same here, it works for DateTime but not for DateTime? for example, it seems it fails with nullable types.

EDIT: I have two sepparate handlers, one for DateTime and another for DateTime?

gusmanb avatar Oct 15 '16 18:10 gusmanb

Ok, this is really nuts, I think I already posted here this solution, but the post is no more, no idea wehat happened or maybe my memory fails, but this is the second time I patch this on the source.

The soultion is really very easy, Dapper is skipping totally all the handlers if the type is of an known DB type.

To solve this, just need to retrieve first the handler and then look for the DB type.

This is the working LookupDbType function:

    public static DbType LookupDbType(Type type, string name, bool demand, out ITypeHandler handler)
    {
        DbType dbType;
        typeHandlers.TryGetValue(type, out handler);
        var nullUnderlyingType = Nullable.GetUnderlyingType(type);
        if (nullUnderlyingType != null) type = nullUnderlyingType;
        if (type.IsEnum() && !typeMap.ContainsKey(type))
        {
            type = Enum.GetUnderlyingType(type);
        }
        if (typeMap.TryGetValue(type, out dbType))
        {
            return dbType;
        }
        if (type.FullName == LinqBinary)
        {
            return DbType.Binary;
        }
        if (handler != null) //typeHandlers.TryGetValue(type, out handler))
        {
            return DbType.Object;
        }
        if (typeof(IEnumerable).IsAssignableFrom(type))
        {
            return DynamicParameters.EnumerableMultiParameter;
        }

        #if !COREFX
        switch (type.FullName)
        {
            case "Microsoft.SqlServer.Types.SqlGeography":
                AddTypeHandler(type, handler = new UdtTypeHandler("geography"));
                return DbType.Object;
            case "Microsoft.SqlServer.Types.SqlGeometry":
                AddTypeHandler(type, handler = new UdtTypeHandler("geometry"));
                return DbType.Object;
            case "Microsoft.SqlServer.Types.SqlHierarchyId":
                AddTypeHandler(type, handler = new UdtTypeHandler("hierarchyid"));
                return DbType.Object;
        }
        #endif
        if(demand)
            throw new NotSupportedException($"The member {name} of type {type.FullName} cannot be used as a parameter value");
        return DbType.Object;

    }

gusmanb avatar Oct 15 '16 19:10 gusmanb

I'm also experiencing this issue, the SetValue is simply ignored.

ccornici avatar Feb 25 '22 08:02 ccornici