有没有办法为 Memcached 序列化 linq 对象? [英] Is there anyway to serilize linq object for Memcached?

查看:26
本文介绍了有没有办法为 Memcached 序列化 linq 对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm just start switching to memcached and currently on testing with memcached.

我有 2 个对象,我创建了一个对象并将 [Serializable] 放在它上面(例如,我们称之为 Object1),另一个对象是使用 Linq DBML 创建的(Object2)..

I'm having 2 object, I created an object and put [Serializable] on it (for instance, let call this Object1), the other object is created using Linq DBML (Object2)..

我尝试对 List 进行内存缓存,它工作得很好,就像魅力一样,这里的一切都被缓存并正确加载.

I tried to memcached List<Object1>, it work just fine, like charm, everything here is cache and loaded properly.

但是,我转到 Linq 对象,现在我尝试添加到 memcached List 这不起作用,它根本没有添加到 memcached.没有添加密钥

But then, i move on to the Linq object, now i try to add to memcached List<Object2> this does not work, it did not add to memcached at all. no key was added

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

I move on and change the Serialization Mode to Unidirectional, do the add again, still no hope.

有没有办法让这个工作?

Is there anyway to make this work?

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

Here is the simple test I just wrote, using MemcachedProvider from codeplex to demonstrate:

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:

this is from Memcached, no STORE was called:

> 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 个查询 => 证明从 Memcached 回调的对象为空,然后它进行查询.

And in my SQL profiler, it called 3 query for 3 test time => Proved that the object called back from Memcached is null, then it query.

推荐答案

看起来默认实现 (DefaultTranscoder) 是使用 BinaryFormatter;单向"的东西是对不同序列化程序(DataContractSerializer)的指令,并且添加[Serializable].

It looks like the default implementation (DefaultTranscoder) is to use BinaryFormatter; the "unidirectional" stuff is an instruction to a different serializer (DataContractSerializer), and doesn't add [Serializable].

(注意:我给自己添加了一个 备忘录 尝试为 memcached 编写一个 protobuf-net 转码器;那会很酷并且可以免费修复大部分)

(Note: I've added a memo to myself to try to write a protobuf-net transcoder for memcached; that would be cool and would fix most of this for free)

我还没有测试过,但有一些选择:

I haven't tested, but a few options present themselves:

  1. 编写一个不同的转码器实现来检测[DataContract]并使用DataContractSerializer,并钩住这个转码器
  2. 通过分部类将 [Serializable] 添加到您的类型(我不相信这会起作用,因为 LINQ 字段类型不可序列化)
  3. 在使用 DataContractSerializer
  4. 的分部类中添加一个 ISerializable 实现
  5. 像 3,但使用 protobuf-net,其中 a: 与单向"一起工作,而 b: 比 DataContractSerializer
  6. 更快更小
  7. 编写一个可序列化的 DTO 并将您的类型映射到那个
  1. write a different transcoder implementation that detects [DataContract] and uses DataContractSerializer, and hook this transcoder
  2. add [Serializable] to your types via a partial class (I'm not convinced this will work due to the LINQ field types not being serializable)
  3. add an ISerializable implementation in a partial class that uses DataContractSerializer
  4. like 3, but using protobuf-net, which a: works with "unidirectional", and b: is faster and smaller than DataContractSerializer
  5. write a serializable DTO and map your types to that

最后一个很简单,但可能会增加更多的工作.

The last is simple but may add more work.

我很想先看第三个选项,因为第一个选项涉及重建提供程序;第四个选项也肯定在我要测试的东西列表中.

I'd be tempted to to look at the 3rd option first, as the 1st involves rebuilding the provider; the 4th option would also definitely be on my list of things to test.

我遇到了 3,因为 DCS 在反序列化过程中返回了一个不同的 对象;我改用 protobuf-net,所以这里有一个版本,它显示了将 partial class 添加到现有的 [DataContract] 类型,使其与 BinaryFormatter 一起使用代码>.实际上,我怀疑(有证据)这也会使它更有效率(比原始 [Serializable]),太:

I struggled with 3, due to the DCS returning a different object during deserialization; I switched to protobuf-net instead, so here's a version that shows adding a partial class to your existing [DataContract] type that makes it work with BinaryFormatter. Actually, I suspect (with evidence) this will also make it much efficient (than raw [Serializable]), too:

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);
        }
    }
}

这篇关于有没有办法为 Memcached 序列化 linq 对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆