加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用自定义SqlMapper.ITypeHandler – Dapper将枚举映射到

发布时间:2020-12-15 22:12:31 所属栏目:百科 来源:网络整理
导读:我有大量的PL / SQL存储过程返回列,其中单个字符串表示固定范围内的某种状态值.在我正在研究的项目中,这些列已经被Dapper映射到域对象上的字符串属性,这些属性管理起来很笨拙且不可靠,所以我想切换到枚举. 如果我使用enum Foo {A,P}之类的单个字符名称的枚举
我有大量的PL / SQL存储过程返回列,其中单个字符串表示固定范围内的某种状态值.在我正在研究的项目中,这些列已经被Dapper映射到域对象上的字符串属性,这些属性管理起来很笨拙且不可靠,所以我想切换到枚举.

如果我使用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实际上并没有调用我的类型处理程序,尽管它已被注册.有没有人知道这方面的方法?

解决方法

另一位用户在Dapper的github网站上报告了这个问题.看起来这是一个专门围绕Dapper枚举的故意优化,所以我改变了我的数据库模型,而不是试图改变映射代码.我看着尝试修改Dapper本身,但Dapper的源代码优化得像我见过的任何东西,发出操作码以最高性能的方式执行转换 – 我不想开始尝试弄清楚如何制作在那里改变.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读