Can dupper handle descriptors be stored in varchar in the database if an explicit constructor is defined?

I have a class that contains an enum type field.

enum myEnum { foo, bar }

class myClass {
    ...

    public myClass(myEnum myField)
    {
        this.myField =myField;
    }
    public myEnum myField {get;set;}
}

      

The enumeration values ​​are stored in the database as varchars (ie "foo", bar "), not as integers.

I want dapper user dapperQuery () to populate my objects but can't get it to work, Dapper keeps complaining that he didn't find a suitable constructor for myClass

I read this question and it seems to mean that what I want to achieve should be possible, but I just can't see how (I am using Dapper 1.38)

I tried adding TypeHandler

for myEnum

but it didn't help.

When I look under the hood, it seems that Dapper is looking TypeHandler

for myClass (in SqlMapper.GetDeserializer()

), does not find it (since mine is TypeHandler

defined for myEnum and goes to callSqlMapper.FindConstructor

Findconstructor doesn't seem to bother with typeHandlers, it just looks for an exact match, checks if myEnum or its base type is the same type as string, indicates it isn't, returns null, and the caller calls ..

Edit: The above code works if you remove the explicit constructor.

+3


source to share


2 answers


Ok I figured it out. It seems dapper can't handle enums if a custom value constructor is defined.

This is because dapper has a special case for handling parameterless constructors (they are automatically assumed to be valid), whereas explicit constructors are type-checked and not accepted in my varchar-enum script.



The reason this is important is because F # record types cannot have any constructors beside the default and therefore Dapper is not handled properly if they contain enumeration members.

I submitted a request to fix this issue.

+2


source


Seems to work fine. Below is test green:



public enum MyTestEnum
{
    Foo,
    Bar
}

public class MyTestClass
{
    public MyTestEnum MyTestEnum { get; set; }
}

public class DapperTests
{
    [Test]
    public void EnumMappingTest()
    {
        DbConnection conn = new SqlConnection(ConfigurationManager.AppSettings["ConnectionString"]);

        var result = conn.Query<MyTestClass>("select MyTestEnum = 'Foo'").First();

        Assert.That(result.MyTestEnum, Is.EqualTo(MyTestEnum.Foo));
    }
}

      

+1


source







All Articles