You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:16:12