DapperLib / DapperLib/Dapper

How to map a single property Dictionary<Guid,string> with a custom ITypeHandler

Open
#225 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 the same issue as the following SO question but the question is missing any answer :(

http://stackoverflow.com/questions/24268378/save-a-dictionary-as-json-in-sql-with-dapper

I'm trying to map a property of type Dictionary<Guid,string> with a ITypeHandler as JSON into a single column in database but will all the time got the following error.

No mapping exists from object type System.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] to a known managed provider native type.'.

The ITypeHandler that I have tried with are the following.

internal class DictionaryGuidStringTypeHandler : SqlMapper.TypeHandler<Dictionary<Guid, string>>
    {
        public override void SetValue(IDbDataParameter parameter, Dictionary<Guid, string> value)
        {
            if (value == null)
            {
                parameter.Value = DBNull.Value;
            }
            else
            {
                parameter.Value = Converter.ConvertObjectToJson(value);
            }
        }

        public override Dictionary<Guid, string> Parse(object value)
        {
            var strValue = value as string;
            if (string.IsNullOrEmpty(strValue))
            {
                return null;
            }
            return Converter.ConvertJsonToObject<Dictionary<Guid, string>>(strValue);
        }
    }
    internal class KeyValuePairGuidStringTypeHandler : SqlMapper.TypeHandler<KeyValuePair<Guid, string>>
    {
        public override void SetValue(IDbDataParameter parameter, KeyValuePair<Guid, string> value)
        {
            if (ReferenceEquals(value, default(KeyValuePair<Guid, string>)))
            {
                parameter.Value = DBNull.Value;
            }
            else
            {
                parameter.Value = Converter.ConvertObjectToJson(value);
            }
        }

        public override KeyValuePair<Guid, string> Parse(object value)
        {
            var strValue = value as string;
            if (string.IsNullOrEmpty(strValue))
            {
                return default(KeyValuePair<Guid, string>);
            }
            return Converter.ConvertJsonToObject<KeyValuePair<Guid, string>>(strValue);
        }
    }
    internal class NullableKeyValuePairGuidStringTypeHandler : SqlMapper.TypeHandler<KeyValuePair<Guid, string>?>
    {
        public override void SetValue(IDbDataParameter parameter, KeyValuePair<Guid, string>? value)
        {
            if (value == null)
            {
                parameter.Value = DBNull.Value;
            }
            else
            {
                parameter.Value = Converter.ConvertObjectToJson(value);
            }
        }

        public override KeyValuePair<Guid, string>? Parse(object value)
        {
            var strValue = value as string;
            if (string.IsNullOrEmpty(strValue))
            {
                return null;
            }
            return Converter.ConvertJsonToObject<KeyValuePair<Guid, string>>(strValue);
        }
    }

Is it possible to map a single property on the class to a specific type-handler by code or with an attribute? My feeling are that the error originating from the part that creating the data reader to class mapping and if that should be possible to override some of that logic on a easy way I think that will solve my problem.

I can always create a shadow property that will make the conversion inside the class to/from json and expose as a string on the class but I hope I can avoid that.

BR
Patric

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 with the ITypeHandler registration and the data-reader-to-class mapping described in the report; check how handlers are selected for a Dictionary<Guid,string> property. Done means determining whether a single property can select a handler by code or attribute, with the reported provider-mapping error reproduced or the supported limitation documented.

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
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.