我的客户端向服务器发送一个json(JObject),我有一个自定义方法,可以将值扁平化为键值对。
假设这是我的json
{
Prop1: 12,
Prop2: "Str",
Prop3:{
Prop4: 222.4
}
}
创建了一个扁平数据字典,如下所示:
"Prop1": 12
"Prop2": "Str"
"Prop3.Prop4": 222.4
现在,我使用Redis(StackExchange.Ris客户端)来保存这些数据。
我生成一个键(例如obj:123456),并将字典的键值添加为散列条目。
数据保存在Redis上,但我的问题是,当我从Redis检索数据时,我需要区分不同的类型。
我注意到了IsInteger
标志,并想尝试将其用作起点。我创建了一个具有整数值的HashEntry
(IsInteger
为true),然后创建了数据HashSetted
。当我使用HashGet
获取数据时,我注意到IsInteger标志为false。
HashSet
和HashGet
之间的IsInteger
标志丢失有什么原因吗?
有什么简单的方法可以处理Redis上的类型(string\int\double\date)吗?我可以考虑一个自定义实现,但我想去那里。
编辑-下面是一个代码示例:
Dictionary<string, object> objs = new Dictionary<string, object>
{
{"Prop1", 12},
{"Prop2", "Str"},
{"Prop3.Prop4", 222.4},
};
var redisConnection = ConnectionMultiplexer.Connect(ConfigurationOptions.Parse("localhost:6379,name=SafeRedisConnection,connectTimeout=100000,syncTimeout=100000,abortConnect=false,defaultDatabase=5"));
// just a test
var hashEntries = objs.Where(kvp => kvp.Value is int).Select(kvp => new HashEntry(kvp.Key, (int)kvp.Value));
var hashEntries1 = objs.Where(kvp => kvp.Value is string).Select(kvp => new HashEntry(kvp.Key, (string)kvp.Value));
var hashEntries2 = objs.Where(kvp => kvp.Value is double).Select(kvp => new HashEntry(kvp.Key, (double)kvp.Value));
var arr = hashEntries.Union(hashEntries1).Union(hashEntries2).ToArray();
redisConnection.GetDatabase().HashSet("obj:123456", arr);
var keys = redisConnection.GetDatabase().HashKeys("obj:123456");
var dic = keys.ToDictionary(k => k, k => redisConnection.GetDatabase().HashGet("obj:123456", k));
您应该使用自己的Redis密钥命名约定。请记住,在Redis中,所有简单值都是字符串(好吧,字节数组……但StackExchange。Redis有一个隐式运算符,可以将RedisValue
转换为string
)。
例如,当您在某个Redis哈希上添加对时,密钥可能是<propertyName>:<type>
,这样您就可以再次将键值转换为CLR类型。。。
另一种方法可以是将这些散列与另一个散列一起存储,以存储密钥的数据类型:
var hashEntries = objs.Where(kvp => kvp.Value is int)
.Select
(
kvp => new HashEntry
(
kvp.Key,
kvp.Value.GetType().AssemblyQualifiedName
)
);
每当您获得部分或全部哈希条目时,您还可以获得其仅元数据对应项来检查每个值类型。
顺便说一句,我认为您应该真正考虑将JSON序列化对象注入全局/分区哈希中,或者使用简单的键串键作为全局键空间的一部分,这样就可以避免这些问题。
如果我需要执行一些操作,比如根据某些属性或其他情况对数据进行索引,我会使用哈希来存储单个属性。。。但是,如果您只是存储完整的对象,请考虑我有目的的方法。