有没有为Memcached序列化linq对象?

时间:2010-01-23 04:10:29

标签: linq-to-sql memcached

我刚刚开始切换到memcached,目前正在使用memcached进行测试。

我有2个对象,我创建了一个对象并在其上放置了[Serializable](例如,让我们调用此Object1),另一个对象是使用Linq DBML创建的(Object2) ..

我尝试了memcached List<Object1>,它工作得很好,就像魅力一样,这里的一切都是缓存并正确加载。

然后,我转到Linq对象,现在我尝试添加到memcached List<Object2>这不起作用,它根本没有添加到memcached。没有添加密钥

我继续将序列化模式改为单向,再次添加,仍然没有希望。

有没有让这项工作?

这是我刚刚编写的简单测试,使用codeplex中的MemcachedProvider来演示:

public ActionResult Test()
{
    var returnObj = DistCache.Get<List<Post>>("testKey");
    if (returnObj == null)
    {
        DataContext _db = new DataContext();
        returnObj = _db.Posts.ToList();
        DistCache.Add("testKey", returnObj, new TimeSpan(29, 0, 0, 0));
        _db.Dispose();
    }

    return Content(returnObj.First().TITLE);
}

这是来自Memcached,没有调用STORE:

> NOT FOUND _x_testKey
>532 END
<528 get _x_testKey
> NOT FOUND _x_testKey
>528 END
<516 get _x_testKey
> NOT FOUND _x_testKey
>516 END

在我的SQL分析器中,它调用3个查询3个测试时间=&gt;证明从Memcached回调的对象为null,然后进行查询。

1 个答案:

答案 0 :(得分:2)

看起来默认的实现(DefaultTranscoder)是使用BinaryFormatter; “单向”内容是指向不同序列化程序(DataContractSerializer)的指令,添加[Serializable]

(注意:我添加了一个memo to myself来尝试为memcached编写一个protobuf-net转码器;这将是 cool 并且可以免费修复大部分内容)

我没有测试过,但有几个选项可供选择:

  1. 编写一个不同的代码转换器实现,检测[DataContract]并使用DataContractSerializer,并挂钩此代码转换器
  2. 通过部分类将[Serializable]添加到您的类型中(由于LINQ字段类型不可序列化,我不相信这会起作用)
  3. 在使用ISerializable
  4. 的部分类中添加DataContractSerializer实现
  5. 喜欢3,但使用protobuf-net,其中a:使用“单向”,b:比DataContractSerializer
  6. 更快更小
  7. 编写可序列化的DTO并将您的类型映射到
  8. 最后一个很简单,但可能会增加更多的工作。

    我很想先看第3个选项,因为第1个选项涉及重建提供者;第四个选项也肯定列在我要测试的事物列表中。


    由于DCS在反序列化期间返回了一个不同的对象,因此我在3中挣扎;我改为使用了protobuf-net,所以这里有一个版本,显示为现有partial class类型添加[DataContract],使其与BinaryFormatter一起使用。实际上,我怀疑(有证据)这也会使它效率高(比原始[Serializable]):

    using System;
    using System.IO;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
    using ProtoBuf;
    
    /* DBML generated */
    namespace My.Object.Model
    {
        [DataContract]
        public partial class MyType
        {
            [DataMember(Order = 1)]
            public int Id { get; set; }
    
            [DataMember(Order = 2)]
            public string Name { get; set; }
        }
    }
    /* Your extra class file */
    namespace My.Object.Model
    {
        // this adds **extra** code into the existing MyType
        [Serializable]   
        public partial class MyType : ISerializable {
            public MyType() {}
            void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
                Serializer.Serialize(info, this);
            }
            protected MyType(SerializationInfo info, StreamingContext context) {
                Serializer.Merge(info, this);
            }
        }
    }
    /* quick test via BinaryFormatter */
    namespace My.App
    {
        using My.Object.Model;
        static class Program
        {
            static void Main()
            {
                BinaryFormatter bf = new BinaryFormatter();
                MyType obj = new MyType { Id = 123, Name = "abc" }, clone;
                using (MemoryStream ms = new MemoryStream())
                {
                    bf.Serialize(ms, obj);
                    ms.Position = 0;
                    clone = (MyType)bf.Deserialize(ms);
                }
                Console.WriteLine(clone.Id);
                Console.WriteLine(clone.Name);
            }
        }
    }