Is there anyway to serilize linq object for Memcached?

后端 未结 1 1421
無奈伤痛
無奈伤痛 2020-12-16 06:24

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

I\'m having 2 object, I created an object and put [Serializable] on it (for instance

相关标签:
1条回答
  • 2020-12-16 06:53

    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].

    (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. 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.


    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);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题