如果定义了显式构造函数,是否可以在数据库中处理存储为varchar的枚举?

时间:2014-11-19 18:59:06

标签: .net enums dapper

我有一个包含枚举类型字段的类。

enum myEnum { foo, bar }

class myClass {
    ...

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

枚举值作为varchars存储在数据库中(即' foo',bar'),而不是整数。

我想用dapper给dapperQuery()来填充我的对象,但是不能让它工作,Dapper一直在抱怨它没有为myClass找到合适的构造函数

我已经阅读了这个question,这似乎意味着我想要实现的目标应该是可能的,但我不知道如何(我使用Dapper 1.38) )

我尝试为TypeHandler添加myEnum,但它没有帮助。

当我查看引擎盖时,似乎Dapper为myClass搜索了TypeHandler(在SqlMapper.GetDeserializer()中),找不到任何内容(因为我的TypeHandler是为myEnum定义的,并继续致电SqlMapper.FindConstructor

Findconstructor似乎并不关心typeHandlers,它只是寻找完全匹配,检查myEnum或它的底层类型是否与string类型相同,并指出它不是,返回null,调用者抛出...

编辑:如果删除显式构造函数,则上述代码有效。

2 个答案:

答案 0 :(得分:2)

好的,我明白了。 如果定义了非默认构造函数,似乎dapper无法处理枚举。

这是因为dapper有一个特殊情况来处理无参数构造函数(它们自动被认为是有效的),而显式构造函数是经过类型检查的,在我的varchar - enum场景中不被接受。

重要的原因是F#记录类型,它不能在默认构造函数旁边有任何构造函数,因此Dapper在包含枚举成员时不能正确处理。

我已提交pull request来解决此问题。

答案 1 :(得分:1)

似乎工作正常。以下测试为绿色:

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));
    }
}