Redis 声明 类 标记的 DataContract 不可序列化?

Redis states that classes marked DataContract are not serializable?

我有以下代码:

[DataContract(Namespace = "removed")]
public class FootballPlayer
{
    /// <summary>
    /// Id of the player.
    /// </summary>
    [DataMember]
    public int Id { get; set; }

/// <summary>
/// Name of the player.
/// </summary>
[DataMember]
public string Name { get; set; }

当我尝试填充我的 redis 缓存时,出现以下错误:

Additional information: Type  'FootballApp.PlayerBase.Contract.FootballPlayer' in Assembly 'FootballApp.PlayerBase.Contract, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

我需要做些什么来告诉 Redis 接受 DataContractSerializer 作为 'accepted' 序列化器(?)以获得更好的术语吗?

我不想返回我所有的 类 并标记为 [Serialiazble] - 我希望 [DataContract] 和 [DataMember] 做(因为它对 AppFabric 很好)那对我来说...

Redis 本身肯定不知道 DataContractAttribute,甚至 .NET 本身也不知道。

StackExchange.Redis,AFAIK,也不知道它,也就是说它没有内置支持 - 至少 a search in the GitHub repository 不会产生一次命中。

以下是我使用 StackExchange.Redis - serialize/deserialize 手动将 "DataContract objects" 存储在 Redis 中所做的操作:

 private static byte[] GetBuffer<T>(T obj) {
     using (var m = new MemoryStream()) {
         var ser = new DataContractSerializer(obj.GetType());
         ser.WriteObject(m, obj);
         return m.ToArray();
     }   
 }

然后您可以从该字节数组构建一个 RedisValue 实例,这是 StackExchange.Redis 用来处理来自 Redis 的 stored/retrieved 值的 "primitive"。

说到检索,您需要反向函数将字节数组反序列化回对象实例:

 private static T GetObject<T>(byte[] buffer) {
     using (var m = new MemoryStream(buffer)) {
        var ser = new DataContractSerializer(typeof(T));
        return (T)ser.ReadObject(m);
     }
 }

当然,您可能希望将这些东西隐藏在一些抽象或扩展方法之后。

最后,您可能想要重新考虑您的设计本身。根据您的应用程序,不将完整的对象(图形)存储为 Redis 中的 blob,而是将单个属性存储为单个键(和关联值)可能是有价值的。因此,如果您只需要一个(或几个)属性,您将不会有 serializing/transfering/deserializing 整个字节块的成本 - 当然您可能会有更多的网络往返。正如我所说,这取决于您的应用程序。

此外,您可以使用 Redis 的 API(甚至 LUA 脚本)有效地操作和处理您的数据,甚至无需首先传输数据。您可以使用 Redis 的 data types 或命名方案(例如 users.<name>.age)来实现这一点。