有没有办法为 Memcached 序列化 linq 对象? [英] Is there anyway to serilize linq object for Memcached?
问题描述
我刚刚开始切换到 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:
- 编写一个不同的转码器实现来检测
[DataContract]
并使用DataContractSerializer
,并钩住这个转码器 - 通过分部类将
[Serializable]
添加到您的类型(我不相信这会起作用,因为 LINQ 字段类型不可序列化) - 在使用
DataContractSerializer
的分部类中添加一个 - 像 3,但使用 protobuf-net,其中 a: 与单向"一起工作,而 b: 比
DataContractSerializer
更快更小 - 编写一个可序列化的 DTO 并将您的类型映射到那个
ISerializable
实现- write a different transcoder implementation that detects
[DataContract]
and usesDataContractSerializer
, and hook this transcoder - 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) - add an
ISerializable
implementation in a partial class that usesDataContractSerializer
- like 3, but using protobuf-net, which a: works with "unidirectional", and b: is faster and smaller than
DataContractSerializer
- 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屋!