使用 dapper 并将一列映射到 json

use*_*372 3 c# dapper

我有一张表,我将字典作为 json 存储在一列中。在将内容保存到/从数据库加载/加载内容时,如果可能,我希望能够使 json 反/序列化不可见。是否可以在不使用包含 json 表示的 Foo 中的另一个属性的情况下以某种方式使用 dapper 来做到这一点?

// where someData is the dictionary column
void Save(IDbConnection conn, Foo foo){
    conn.Execute("INSERT INTO foos (name, <othercols...>, someData) VALUES (@Name, <othercols...>, @SomeData, foo);
}
Run Code Online (Sandbox Code Playgroud)

我可以手动将 Foo 映射到一个新的动态对象中,但是因为有其他列会很乏味,所以我想知道是否还有其他方法?

Lak*_*mon 6

您可以通过实现 ITypeHandler 来实现它。

示例实现Dictionary<int, string>

class DictTypeHandler : ITypeHandler
{
    public object Parse(Type destinationType, object value)
    {
        return JsonConvert.DeserializeObject<Dictionary<int, string>>(value.ToString());
    }

    public void SetValue(IDbDataParameter parameter, object value)
    {
        parameter.Value = (value == null)
            ? (object)DBNull.Value
            : JsonConvert.SerializeObject(value);
        parameter.DbType = DbType.String;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您将 Dapper 添加到其已知处理程序中,则 Dapper 将使用该处理程序 SqlMapper.AddTypeHandler(typeof(DictTypeHandler), new DictTypeHandler())

IDbDataParameter.DbType如果您的 sql 列是 varchar(max),请注意设置为 string,否则 Dapper 将使用无法转换为 varchar(max) 的 sql_variant。

如果您通过存储库模式实现持久性,则可以将AddTypeHandler代码添加到构造函数中。