【问题标题】:Is there anyway to serilize linq object for Memcached?无论如何要为 Memcached 序列化 linq 对象吗?
【发布时间】:2011-01-08 11:43:41
【问题描述】:

我刚开始切换到 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 次测试时间 => 证明从 Memcached 回调的对象为空,然后进行查询。

【问题讨论】:

  • 这个问题可能受益于 (1) 一些代码示例 (2) 更清楚地解释究竟出了什么问题,以及 (3) 您究竟是如何使用 .NET 中的 memcached。有多个 .NET 包装器,它们在这方面的行为可能不尽相同。
  • 我添加了您需要的所有内容。我使用的包装器是来自 codeplex 的 MemcachedProvider。 object1 已成功添加,但不知何故 linq 对象没有。
  • 额外信息有帮助,但我看不出有什么问题。您是否调试过 Add() 调用?使用 TCP 代理或 Wireshark 来查看 MemcachedProvider 是否为这个请求向 memcached 发送任何东西怎么样?
  • add 调用 do 只是对 memcached 的 Erym(或其他东西)包装器的调用。我在源文件中认为这没有问题。我将尝试获取另一个包装器,看看是否是因为 MemCachedProvider 问题。但与此同时,如果有人知道任何事情或经历过任何事情,请帮助我。我的想法是找到一种将序列化添加到 linq 对象的方法
  • 作为参考,我为此场景编写了一个 protobuf-net 包装器;你可以“按原样”使用它,或者你可以写一些非常相似的东西并使用 DataContractSerializer。博客:marcgravell.blogspot.com/2010/01/…,代码:code.google.com/p/protobuf-net/source/browse/trunk/…

标签: linq-to-sql memcached


【解决方案1】:

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

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

我没有测试过,但有几个选项会出现:

  1. 编写检测[DataContract] 并使用DataContractSerializer 的不同转码器实现,并挂钩此转码器
  2. 通过部分类将 [Serializable] 添加到您的类型(由于 LINQ 字段类型不可序列化,我不相信这会起作用)
  3. 在使用DataContractSerializer 的部分类中添加ISerializable 实现
  4. 与 3 类似,但使用 protobuf-net,其中 a: 适用于“单向”,b: 比 DataContractSerializer 更快且更小
  5. 编写一个可序列化的 DTO 并将您的类型映射到 那个

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

我很想先看看第三个选项,因为第一个涉及重建提供程序;第四个选项也肯定在我的测试清单上。


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

【讨论】:

  • 我对您的问题添加了一些评论,您可以查看一下吗?
猜你喜欢
  • 2016-02-08
  • 1970-01-01
  • 2016-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
  • 2011-09-05
相关资源
最近更新 更多