使用StackExchange.Redis调用Lua函数后无法转换JSON结果的问题
问题:StackExchange.Redis调用Redis自定义函数无法转换JSON集合结果
使用C#的StackExchange.Redis包调用Redis自定义Lua函数获取JSON集合数据时,无法将RedisResult转换为List<ElementBusinessModel>、列表或字符串数组,尝试多种方法均无效。
原C#代码
string pattern = $"Slips:{obj.Id}:{obj.Team}:{oppositeType}:*"; // 获取Redis中的所有元素 var elEntries = await database.SortedSetRangeByRankAsync(redisKey, 0, -1); var result = await database.ExecuteAsync("FCALL", "GetEls", 0, redisKey); // 尝试过的转换方式 var elements = result.As<List<ElementBusinessModel>>(); // 假设result是keys集合,尝试逐个处理 foreach (var key in keys) { string json = key.ToString(); if (!string.IsNullOrEmpty(json)) { var betObject = JsonSerializer.Deserialize<ElementBusinessModel>(json); } }
原Redis自定义Lua函数
-- 自定义FCALL函数 FUNCTION LOAD "#!lua name=myLib redis.register_function('GetEls', function(keys, args) local pattern = args[1] local cursor = '0' local bets = {} repeat local result = redis.call('SCAN', cursor, 'MATCH', pattern, 'COUNT', 100) cursor = result[1] local keysList = result[2] for _, key in ipairs(keysList) do local betJson = redis.call('JSON.GET', key) if betJson then table.insert(els, elsJson) end end until cursor == '0' return els end)"
解决方案
1. 修复Lua函数的变量错误
原Lua函数存在变量名不一致和语法问题,导致返回结果异常:
- 定义的集合变量是
bets,但插入时误用了未定义的els - 获取的JSON变量是
betJson,插入时误用了未定义的elsJson for语句的do位置不符合Lua语法规范
修改后的Lua函数:
FUNCTION LOAD "#!lua name=myLib redis.register_function('GetEls', function(keys, args) local pattern = args[1] local cursor = '0' local bets = {} repeat local result = redis.call('SCAN', cursor, 'MATCH', pattern, 'COUNT', 100) cursor = result[1] local keysList = result[2] for _, key in ipairs(keysList) do local betJson = redis.call('JSON.GET', key) if betJson then table.insert(bets, betJson) end end until cursor == '0' return bets end)"
2. 正确转换StackExchange.Redis的RedisResult
StackExchange.Redis的RedisResult无法直接通过As<T>转换为自定义集合类型,需先将其转换为RedisValue[],再逐个反序列化:
修改后的C#代码:
string pattern = $"Slips:{obj.Id}:{obj.Team}:{oppositeType}:*"; var result = await database.ExecuteAsync("FCALL", "GetEls", 0, pattern); // 将RedisResult转换为RedisValue数组并反序列化 if (result.IsArray) { var jsonValues = (RedisValue[])result; var elements = new List<ElementBusinessModel>(); foreach (var jsonValue in jsonValues) { if (!jsonValue.IsNull && jsonValue.HasValue) { var model = JsonSerializer.Deserialize<ElementBusinessModel>(jsonValue.ToString()); elements.Add(model); } } // 此处可直接使用elements集合 }
内容的提问来源于stack exchange,提问作者shivam gupta
相关产品推荐
相关产品推荐

