是否有选项可以在 Dapper 中为 QueryFirstAsync

我正在尝试将对象从 sql 映射到 C# 中的多个对象。在具有 QueryFirstAsync 和 QueryFirstOrDefaultAsync 的情况下如何进行多重映射?


我尝试过类似于 QueryAsync 或 Query 中的过程。


ClassA record = 

await this.dbConnection.QueryFirstAsync<ClassA, ClassB, ClassA>(

sql,                   

(a, b) =>

{

  a.Id = b.Id;                                                                           

  return a;

},

splitOn: "Id",

param: new

{

  memberId

});

我期望构建成功,但它不适用于 QueryFirstAsync 或 QueryFirstOrDefaultAsync。


森林海
浏览 111回答 1
1回答

蝴蝶刀刀

当前的问题:您正在尝试将多重映射与 dapper 函数QueryFirstAsync和 一起使用QueryFirstOrDefaultAsync,但它们的重载都不支持 Mutli-Mapping,如 所做的那样QueryAsync,粘贴来自 Dapper 代码的定义:public static Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TReturn>(this IDbConnection cnn,&nbsp;CommandDefinition command, Func<TFirst, TSecond, TReturn> map, string splitOn = "Id") =>&nbsp;MultiMapAsync<TFirst, TSecond, DontMap, DontMap, DontMap, DontMap, DontMap, TReturn>(cnn,&nbsp;command, map, splitOn);它调用MultiMapAsync,它利用该SplitOn值创建多地图默认值是Idprivate static async Task<IEnumerable<TReturn>> MultiMapAsync<TReturn>(this IDbConnection cnn, CommandDefinition command, Type[] types, Func<object[], TReturn> map, string splitOn)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (types.Length < 1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new ArgumentException("you must provide at least one type to deserialize");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; object param = command.Parameters;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var identity = new Identity(command.CommandText, command.CommandType, cnn, types[0], param?.GetType(), types);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var info = GetCacheInfo(identity, param, command.AddToCache);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bool wasClosed = cnn.State == ConnectionState.Closed;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (wasClosed) await cnn.TryOpenAsync(command.CancellationToken).ConfigureAwait(false);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; using (var cmd = command.TrySetupAsyncCommand(cnn, info.ParamReader))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; using (var reader = await ExecuteReaderWithFlagsFallbackAsync(cmd, wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult, command.CancellationToken).ConfigureAwait(false))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var results = MultiMapImpl(null, default(CommandDefinition), types, map, splitOn, reader, identity, true);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return command.Buffered ? results.ToList() : results;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; finally&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (wasClosed) cnn.Close();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }解决方案:使用 standard QueryAsync,它有一个重载,SplitOn在最终结果调用上采用 和FirstorDefault,因为 Dapper 查询的结果是IEnumerable<T>,因此可以调用任何标准 Linq 扩展方法
打开App,查看更多内容
随时随地看视频慕课网APP