如何将Task<IEnumerable<dynamic>>返回结果转换为MessageQueue类型集合
原有代码错误原因
- 调用异步方法使用
.Result,存在上下文死锁风险,异步方法推荐使用await调用 - Dapper返回的
dynamic实际是内部DapperRow类型,没有继承你定义的MessageQueue类,无法直接强转,强制转换会抛出类型不匹配异常 - 代码中出现的
MessageQueueToSendRet与目标类型MessageQueue不一致,也是报错诱因
正确实现方案
方案1:修改DataFromDatabase方法返回强类型(优先选择,性能最好)
直接在Dapper读取结果时指定强类型,不需要走dynamic中转:
public async Task<IEnumerable<MessageQueue>> DataFromDatabase() { // 这里是你原有的数据库连接初始化逻辑 using var dbConnection = // 你的数据库连接实例 var multiResult = await dbConnection.QueryMultipleAsync(/* 你的SQL语句、参数配置 */); // 直接读取为MessageQueue强类型集合 return await multiResult.ReadAsync<MessageQueue>(); }
调用代码:
List<MessageQueue> messageQueue = (await srv.DataFromDatabase()).ToList();
方案2:无法修改DataFromDatabase返回类型的场景
如果必须处理IEnumerable<dynamic>结果,可采用以下两种方式转换:
方式1:手动映射字段(性能最优)
// 先await拿到dynamic结果集,不要用.Result IEnumerable<dynamic> dynamicData = await srv.DataFromDatabase(); List<MessageQueue> messageQueue = dynamicData.Select(item => new MessageQueue { MsgTitle = item.MsgTitle, ClientID = item.ClientID, UserID = item.UserID }).ToList();
注意:需要确保dynamic对象中的字段名和MessageQueue的属性名完全对应,不存在字段缺失的情况
方式2:序列化中转(适合字段多、不想手动写映射的场景)
using System.Text.Json; IEnumerable<dynamic> dynamicData = await srv.DataFromDatabase(); // 配置忽略大小写适配不同命名规范的字段 var jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; List<MessageQueue> messageQueue = JsonSerializer.Deserialize<List<MessageQueue>>( JsonSerializer.Serialize(dynamicData, jsonOptions), jsonOptions );
内容的提问来源于stack exchange,提问作者Francis Irasa
相关产品推荐
相关产品推荐

