2010-01-23 1 views
5

Я только начинаю переходить на memcached и в настоящее время тестировать с memcached.Есть ли все-таки для serilize объекта linq для Memcached?

У меня 2 объекта, я создал объект и поместить [Serializable] на нем (например, пусть называют это Object1), другой объект создается с помощью Linq DBML (Object2) ..

I попытался memcached List<Object1>, он работает просто отлично, как шарм, все здесь кеш и загружается правильно.

Но тогда я перехожу к объекту Linq, теперь я пытаюсь добавить в memcached List<Object2>, это не сработает, оно вообще не добавлено в memcached. ключ не был добавлен

Я перехожу и меняю режим сериализации на однонаправленный, добавьте еще раз, пока нет надежды.

Есть ли все, чтобы сделать эту работу?

Вот простой тест, который я только что написал, используя MemcachedProvider из CodePlex, чтобы продемонстрировать:

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 Profiler, он вызвал 3 запроса для 3-х тестового времени => Доказано, что возвращаемый объект из Memcached имеет значение null, затем он запрашивает.

+0

Этот вопрос может извлечь выгоду из (1) Некоторые образцы кода (2) более четкое объяснение того, что происходит не так точно и (3) Как именно вы используете memcached из .NET. Есть несколько оболочек .NET, и они могут не все вести себя одинаково в этом отношении. –

+0

Я добавил все, что вам нужно. Использование wraper im - MemcachedProvider из codeplex. Объект1 был успешно добавлен, но каким-то образом объект linq этого не сделал. – DucDigital

+0

Дополнительная информация помогает, но я не вижу проблемы. Вы отлаживали вызов Add()? Как насчет использования прокси-сервера TCP или Wireshark, чтобы узнать, даже ли MemcachedProvider отправляет что-либо в memcached для этого запроса? –

ответ

2

Похоже, что реализация по умолчанию (DefaultTranscoder) предназначена для использования BinaryFormatter; «однонаправленный» материал является инструкцией для другого сериализатора (DataContractSerializer), а не добавить [Serializable].

(Примечание: Я добавил memo to myself, чтобы попытаться написать Protobuf-сеть транскодер для Memcached, это было бы круто и исправит большинство это бесплатно)

Я не проверял, но несколько вариантов представить себя:

  1. написать другую реализацию транскодер, который детектирует [DataContract] и использует DataContractSerializer и зацепить этот транскодер
  2. добавить [Serializable] к вашим типам с помощью частичного класса (Я не уверен, что это будет работать в связи с типами полей LINQ не будучи сериализуемых)
  3. добавить ISerializable реализацию в частичном классе, который использует DataContractSerializer
  4. как 3, но с использованием Protobuf-сеть, которой: работает с «однонаправленный», и б: быстрее и меньше DataContractSerializer
  5. написать сериализации DTO и сопоставить типы для что

Последнее является простой, но может добавить больше работы.

У меня возникнет соблазн сначала взглянуть на третий вариант, так как первый включает в себя перестройку поставщика; 4-й вариант также будет определенно быть в моем списке вещей для тестирования.


я боролся с 3, в связи с DCS возвращая другого объекта во время десериализации; Вместо этого я переключился на 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); 
     } 
    } 
} 
+0

Я добавил комментарий к вашей проблеме, вы можете проверить? – DucDigital

Смежные вопросы