为什么foreach循环无法遍历Json反序列化得到的dynamic值并报类型转换错误
报错原因
当前us.Value存储的是单个数值1,反序列化后得到的dynamic实际是long类型,不属于可迭代的IEnumerable类型,foreach无法对单个数值做遍历,所以抛出类型转换错误。
兼容单值/多值场景的解决方案
方案1:兼容现有存量数据(无需修改存储逻辑)
用JToken接收反序列化结果,判断数据类型后统一转为int集合再遍历:
using Newtonsoft.Json.Linq; // 统一反序列化为JToken做类型判断 JToken idsToken = JsonConvert.DeserializeObject<JToken>(us.Value); IEnumerable<int> idsList; if (idsToken.Type == JTokenType.Array) { // 多值场景:直接转为int集合 idsList = idsToken.ToObject<List<int>>(); } else { // 单值场景:包装为单元素集合 idsList = new List<int> { idsToken.ToObject<int>() }; } foreach (int id in idsList) { // 注意原代码LINQ的Where首字母需要大写 var v = db.subs.Where(s => s.Id == id).FirstOrDefault(); // 后续业务逻辑 }
说明:如果使用的是非常老版本的Entity Framework,存在闭包捕获循环变量的问题,可以再把id赋值给循环内的临时变量使用。
方案2:优化存储逻辑(推荐)
如果可以调整存库逻辑,不管是单个值还是多个值,序列化时统一转为数组格式存储(比如单个值1存为[1]),反序列化时可以直接用List<int>接收,不需要额外做类型判断,代码更简洁稳定:
List<int> ids = JsonConvert.DeserializeObject<List<int>>(us.Value); foreach (int id in ids) { var v = db.subs.Where(s => s.Id == id).FirstOrDefault(); // 后续业务逻辑 }
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

