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

C#中如何将List<T>存入Redis并支持分页与多列排序?

在C#中实现Redis存储List并支持多列分页排序的方案

答案是可以实现,且无需为不同排序列重复插入数据,以下是几种可行方案:

方案一:RedisJSON + RedisSearch(推荐)

  • 把List<T>中的每个实体序列化为JSON,用Redis原生JSON类型(Redis 6.2+支持)存储,每个实体分配唯一ID作为Key,例如entity:{实体ID}。
  • 利用RedisSearch创建全局索引,指定所有需要排序的字段(如Name、CreateTime、Score等),索引只需创建一次。
  • 查询时直接通过RedisSearch命令指定排序字段、分页参数(偏移量+条数),即可直接获取分页排序后的结果,无需冗余存储。
  • C#代码示例(基于NRedisStack库):
    // 序列化并存储单个实体
    var entityJson = JsonSerializer.Serialize(myEntity);
    db.Json.Set($"entity:{myEntity.Id}", "$", entityJson);
    
    // 创建索引(仅需执行一次)
    db.CreateIndex("entities_index", 
        new FTCreateIndexOptions().On(IndexDataType.Json).Prefix("entity:"),
        new Schema()
            .AddSortableField("$.Name")
            .AddSortableField("$.CreateTime")
            .AddSortableField("$.Score")
    );
    
    // 按CreateTime降序分页查询(第2页,每页10条)
    var searchResult = db.Search("entities_index", 
        new Query("*").SortBy("$.CreateTime", Order.Descending).Limit(10, 10)
    );
    
    // 反序列化为List<T>
    var sortedEntities = searchResult.Documents
        .Select(doc => JsonSerializer.Deserialize<T>(doc.ToString()))
        .ToList();
    
  • 优势:一次存储支持多字段排序、分页、复杂过滤,性能优异,无冗余数据。

方案二:Hash存储实体 + 复合键SortedSet

如果无法依赖RedisSearch模块,可通过构造复合排序键实现多规则排序:

  • 将每个实体存入Redis Hash,Key为entity:{实体ID},字段对应实体的各个属性。
  • 创建一个SortedSet,成员为实体ID,排序键用复合字符串拼接(需保证字典序与实际排序逻辑一致),例如按CreateTime降序+Score升序,可构造键为{反转时间字符串}_{补零后的Score}。
  • 查询时通过SortedSet的范围命令分页获取实体ID,再批量从Hash中取出实体。
  • C#代码示例:
    // 存储实体到Hash
    db.HashSet($"entity:{entity.Id}", new HashEntry[]
    {
        new HashEntry("Name", entity.Name),
        new HashEntry("CreateTime", entity.CreateTime.ToString("o")),
        new HashEntry("Score", entity.Score.ToString("D8")) // 补前导零保证长度一致
    });
    
    // 构造复合排序键(时间反转实现降序)
    var reverseTime = new string(entity.CreateTime.ToString("yyyyMMddHHmmss").Reverse().ToArray());
    var sortKey = $"{reverseTime}_{entity.Score.ToString("D8")}";
    // 将复合键作为SortedSet的成员,分数设为0,利用字典序排序
    db.SortedSetAdd("entities_sort", sortKey, 0);
    
    // 分页获取排序后的实体ID
    var sortedKeys = db.SortedSetRangeByLex("entities_sort", "-", "+", order: Order.Ascending, skip: 10, take: 10);
    var entityIds = sortedKeys.Select(k => k.Split('_')[1]); // 解析出实体ID
    
    // 批量获取实体并映射为T类型
    var entities = entityIds.Select(id => MapHashToEntity<T>(db.HashGetAll($"entity:{id}"))).ToList();
    
  • 注意:复合键的构造需严格保证字典序与业务排序逻辑匹配,适合排序规则相对固定的场景。

方案三:应用层分页排序(仅适合小数据集)

  • 将整个List<T>序列化为JSON字符串存入Redis String类型。
  • 取出时反序列化为List<T>,通过C# Linq完成分页排序:
    var listJson = db.StringGet("full_entity_list");
    var entityList = JsonSerializer.Deserialize<List<T>>(listJson);
    var sortedPage = entityList.OrderBy(x => x.Name).Skip(10).Take(10).ToList();
    
  • 劣势:数据量大时序列化/反序列化开销极高,占用内存大,性能差。

内容的提问来源于stack exchange,提问作者ivan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 05:37:12