如何使Dapper.NET将未映射的列映射到字典?

时间:2019-07-08 16:58:21

标签: c# dapper

通过允许选择一些动态SQL,我的表将具有一些已知的列和一些未知的列。我正在寻找没有匹配属性的任何列添加到字典中。基于关于How can I make Dapper.NET throw when result set has unmapped columns?的另一个问题,但我不想抛出错误,而是希望将这些列映射到将在该类上的字典中。

public SqlMapper.IMemberMap GetMember( string columnName ) {
            var fallbackMappers = new List<SqlMapper.ITypeMap>();
            fallbackMappers.Add( _defaultTypeMap );

            var fallbackTypeMapper = new FallbackTypeMapper(fallbackMappers);

            var member = fallbackTypeMapper.GetMember(columnName);
            if(member == null ) {
                throw new Exception();
            }
            return member;
        }
//...
public static async Task<IEnumerable<T>> QueryAsyncOtherProps<T>(
            this IDbConnection cnn,
            string sql,
            object param = null,
            IDbTransaction transaction = null,
            int? commandTimeout = default,
            CommandType? commandType = default
        )
            where T : BaseSimpleType {
            lock ( _lock ) {
                if ( TypesThatHaveMapper.ContainsKey( typeof( T ) ) == false ) {
                    SqlMapper.SetTypeMap( typeof( T ), new NullTypeMapToOtherProperties<T>() );
                    TypesThatHaveMapper.Add( typeof( T ), null );
                }
            }
            return await cnn.QueryAsync<T>( sql, param, transaction, commandTimeout, commandType );
        }

我的BaseSimpleType仅包含一个名为OtherProperties的字典属性,因此只能在具有该字段且名称一致的类型上调用此属性。有没有其他方法可以尝试使用Dapper做到这一点?

1 个答案:

答案 0 :(得分:0)

我有同样的要求,我想将记录的所有缺失字段映射到 IDictionary<string, object> field。我已经搜索了足够长的时间,我决定自己实现它。

我创建了一个 Dapper Extension 类。它只包含一个新方法:.QueryWithExtraFields() 并作为参数传递一个 Action 函数,该函数将为每一行调用,该函数将接收类 T 实例和一个 {{1 }} 未映射的每个字段。

使用此 IDictionary<string,object> 参数,您可以控制将其设置在您的类中或使用未映射的字段执行其他操作。

预期的 Dapper Return Class

Action<>

使用

private class ReturnTestClass
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IDictionary<string,object> ExtraFields { get; set; }
}

DapperExtension.cs 类代码:

var results = dbConnection.QueryWithExtraFields<ReturnTestClass>(
    sql: "select 1 id, 'Test' as Name, 2 as FieldNumber2, 'other field' as FieldNumber3",
    unmappedFieldsAction: (o, unmappedFields) => o.ExtraFields= unmappedFields); //Here is where you place the dictionary inside you type `T` class
相关问题