如何通过StackExchange.Redis将通用列表添加到Redis?

Sha*_*ane 13 c# redis stackexchange.redis

例如,如果我有一个名为Customer的模型

public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Address1 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

例:

var customers = new List<Customer>();
Run Code Online (Sandbox Code Playgroud)

我如何添加客户列表?我该怎么做?

 using (var redis = ConnectionMultiplexer.Connect(this.redisServer))
            {
                var db = redis.GetDatabase();

                db.SetAdd(key, ?????);
}
Run Code Online (Sandbox Code Playgroud)

我认为SetAdd是正确的方法,但我无法看到如何获取我的Customer通用列表(即List为RedisValue的格式.

And*_*bal 16

可能有帮助.在我潜入StackExchange.Redis之初,我也遇到了同样的问题.在我的项目中,我创建了2个扩展方法,这有助于我为Redis数据库序列化/反序列化复杂类型.您可以根据自己的需要进行扩展.

方法:

    public static class RedisUtils
        {
//Serialize in Redis format:
            public static HashEntry[] ToHashEntries(this object obj)
            {
                PropertyInfo[] properties = obj.GetType().GetProperties();
                return properties.Select(property => new HashEntry(property.Name, property.GetValue(obj).ToString())).ToArray();
            }
    //Deserialize from Redis format
            public static T ConvertFromRedis<T>(this HashEntry[] hashEntries)
            {
                PropertyInfo[] properties = typeof(T).GetProperties();
                var obj = Activator.CreateInstance(typeof(T));
                foreach (var property in properties)
                {
                    HashEntry entry = hashEntries.FirstOrDefault(g => g.Name.ToString().Equals(property.Name));
                    if (entry.Equals(new HashEntry())) continue;
                    property.SetValue(obj, Convert.ChangeType(entry.Value.ToString(), property.PropertyType));
                }
                return (T)obj;
            }
        }
Run Code Online (Sandbox Code Playgroud)

用法:

var customer = new Customer
{
//Initialization
};

Db.HashSet("customer", customer.ToHashEntries());
Customer result = Db.HashGetAll("customer").ConvertFromRedis<Customer>();

Assert.AreEqual(customer.FirstName, result.FirstName);
Assert.AreEqual(customer.LastName, result.LastName);
Assert.AreEqual(customer.Address1, result.Address1);
Run Code Online (Sandbox Code Playgroud)


Mar*_*ell 14

StackExchange.Redis是一个原始客户端 - 它只用Redis术语.它不会尝试成为任何类型的ORM.但是,它会存储你想要的任何stringbyte[]那个 - 这意味着你应该选择序列化器.虽然我们倾向于使用协议缓冲区(通过protobuf-net),但JSON将是一个合理的默认值(Jil很棒).

你打算使用列表语义,我强烈建议从List*命令开始 - 集合对列表有不同的语义 - 集合是无序的,只存储唯一值; 列表保留顺序并允许重复.

  • @Shane有两个选项 - 如果你想使用redis的列表功能,请单独序列化每个对象**并作为单独的列表行发送.如果你只想"存储我的列表,获取我的列表" - 那么:序列化*list*并使用String*redis函数.redis"字符串"只是意味着"单个值" - 它不需要是*字符串*(如果这有意义) (3认同)

von*_* v. 8

改进了Andrey Gubal的答案,处理可空属性或空值:

public static class RedisUtils
{
    //Serialize in Redis format:
    public static HashEntry[] ToHashEntries(this object obj)
    {
        PropertyInfo[] properties = obj.GetType().GetProperties();
        return properties
            .Where(x=> x.GetValue(obj)!=null) // <-- PREVENT NullReferenceException
            .Select(property => new HashEntry(property.Name, property.GetValue(obj)
            .ToString())).ToArray();
    }

    //Deserialize from Redis format
    public static T ConvertFromRedis<T>(this HashEntry[] hashEntries)
    {
        PropertyInfo[] properties = typeof(T).GetProperties();
        var obj = Activator.CreateInstance(typeof(T));
        foreach (var property in properties)
        {
            HashEntry entry = hashEntries.FirstOrDefault(g => g.Name.ToString().Equals(property.Name));
            if (entry.Equals(new HashEntry())) continue;
            property.SetValue(obj, Convert.ChangeType(entry.Value.ToString(), property.PropertyType));
        }
        return (T)obj;
    }
}
Run Code Online (Sandbox Code Playgroud)