使用自定义的SqlMapper.ITypeHandler将枚举映射到字符串列 - Dapper

7
我有许多PL/SQL存储过程,返回由单个字符表示的某种来自固定范围的状态值。在我现在的项目中,这些列已经被映射到域对象上的字符串属性,但是管理起来很麻烦且不可靠,因此我想切换到枚举。
如果我使用像enum Foo {A, P}这样的单字符名称的枚举,我相信Dapper会正确地将它们映射,但我不想要那样,我想要带有描述性标签的枚举,如下所示:
enum Foo {
    [StringValue("A")]
    Active,
    [StringValue("P")]
    Proposed
}

在上面的示例中,StringValueAttribute是一个自定义属性,我可以使用反射将"A"转换为Foo.Active,这样可以正常工作,但我需要Dapper来执行该转换逻辑。我编写了一个自定义类型处理程序来实现这一点:
public class EnumTypeHandler<T> : SqlMapper.TypeHandler<T>
{
    public override T Parse(object value)
    {
        if (value == null || value is DBNull) { return default(T); }
        return EnumHelper.FromStringValue<T>(value.ToString());
    }

    public override void SetValue(IDbDataParameter parameter, T value)
    {
        parameter.DbType = DbType.String;
        parameter.Value = EnumHelper.GetStringValue(value as Enum);
    }
}

//Usage:
SqlMapper.AddTypeHandler(typeof(Foo),
    (SqlMapper.ITypeHandler)Activator.CreateInstance(typeof(EnumTypeHandler<>).MakeGenericType(typeof(Foo)));

SqlMapper.AddTypeHandler() 方法的注册看起来很正常,但当我的 DbConnection.Query() 代码运行时,会出现一个错误,其中指出值“A”无法转换-错误是从 Enum.Parse 抛出的,这表明尽管已经注册了类型处理程序,但 Dapper 实际上并没有调用它。有人知道如何解决这个问题吗?

1个回答

2

另一个用户在Dapper的github站点上报告了这个问题。看起来这是针对Dapper中枚举类型的有意优化,因此我改变了我的数据库模型而不是尝试更改映射代码。我曾试图修改Dapper本身,但Dapper的源代码被优化得像我从未见过的那样,发出操作码以以最有效的方式执行转换 - 我绝不想开始尝试如何进行更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接