我有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)); _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
解决方法
(注意:我已经添加了一个memo to myself来尝试为memcached编写一个protobuf-net转码器;这很酷并且可以免费修复大部分内容)
我没有测试过,但有几个选项可供选择:
>编写一个不同的代码转换器实现,检测[DataContract]并使用DataContractSerializer,并挂钩此代码转换器
>通过部分类将[Serializable]添加到您的类型中(由于LINQ字段类型不可序列化,我不相信这会起作用)
>在使用DataContractSerializer的分部类中添加ISerializable实现
>喜欢3,但使用protobuf-net,其中a:使用“单向”,而b:比DataContractSerializer更快更小
>编写可序列化的DTO并将您的类型映射到该DTO
最后一个很简单,但可能会增加更多的工作.
我很想先看第3个选项,因为第1个选项涉及重建提供者;第四个选项也肯定会列在我要测试的东西列表中.
由于DCS在反序列化期间返回了不同的对象,我在3中挣扎;我转而使用protobuf-net,所以这里有一个版本,它显示了为现有的[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); } } }