Сериализация графов объектов с использованием сериализатора MongoDB Bson - PullRequest
1 голос
/ 03 июня 2011

Я немного поигрался с сериализатором Bson MongoDB, используя следующий фрагмент кода:

class Program
{
    public class myValue
    {
        public int Id = 0;
        public string Label = "";
    }

    public class myValueMap : Dictionary<string, myValue>
    {
    }

    public class myProdData
    {
        public myValueMap  Mapping { get; set; }

    }
    public class mySystemPosition
    {
        public string Text { get; set; }
        public myProdData ProdData { get; set; }

    }
    static void Main(string[] args)
    {
        BsonClassMap.RegisterClassMap<mySystemPosition>();
        BsonClassMap.RegisterClassMap<myProdData>();
        BsonClassMap.RegisterClassMap<myValueMap>();
        BsonClassMap.RegisterClassMap<myValue>();
        var o = new mySystemPosition()
                    {
                        ProdData = new myProdData()
                                       {
                                           Mapping = new myValueMap()
                                                        {
                                                            {"123", new myValue() {Id = 1, Label = "Item1"}},
                                                            {"345", new myValue() {Id = 2, Label = "Item2"}},
                                                        }
                                       }
                    };
        var bson = o.ToBson();

        var text = Encoding.ASCII.GetString(bson);
    }
}

, однако я не могу получить сериализацию myProdData.Mapping ....

Нужно ли настраивать сериализатор MongoDB Bson специальным образом, чтобы это работало?

Ответы [ 3 ]

0 голосов
/ 03 июня 2011

Проблема в том, что myValueMap является производным от словаря. В результате получается класс, который метод AutoMap не может обработать.

Я рекомендую вам просто использовать словарь напрямую, как это сделал Эндрю в своем ответе.

0 голосов
/ 06 июня 2011

К сожалению, myValueMap - это объект, который я не могу легко изменить, однако оказывается, что довольно легко создать свой собственный (де) сериализатор ....

    public class myValueMapSerializer : IBsonSerializer
    {
        public object Deserialize(Bson.IO.BsonReader bsonReader, System.Type nominalType, System.Type actualType, IBsonSerializationOptions options)
        {
            if (nominalType != typeof(myValueMap)) throw new ArgumentException("Cannot serialize anything but myValueMap");
            var res = new myValueMap();
            var ser = new DictionarySerializer<string, myValue>();
            var dic = (Dictionary<string, myValue>)ser.Deserialize(bsonReader, typeof(Dictionary<string, myValue>), options);

            foreach (var item in dic)
            {
                res.Add(item.Key, item.Value);
            }
            return res;
        }

        public object Deserialize(Bson.IO.BsonReader bsonReader, System.Type nominalType, IBsonSerializationOptions options)
        {
            throw new Exception("Not implemented");
        }

        public bool GetDocumentId(object document, out object id, out IIdGenerator idGenerator)
        {
            id = null;
            idGenerator = null;
            return false;
        }

        public void Serialize(Bson.IO.BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
        {
            if (nominalType != typeof(myValueMap)) throw new ArgumentException("Cannot serialize anything but myValueMap");

            var ser = new DictionarySerializer<string, myValue>();
            ser.Serialize(bsonWriter, typeof(DictionarySerializer<string, myValue>), value, options);
        }

        public void SetDocumentId(object document, object id)
        {
            return;
        }
    }
0 голосов
/ 03 июня 2011

Вам не нужно использовать BsonClassMap.RegisterClassMap, если вам не нужна настраиваемая сериализация ( документация ).Все ваши классы будут десиализованы в соответствии с правилами по умолчанию.

Также я немного изменил ваш пример, чтобы он заработал (я заменил myValueMap класс на Словарь):

    public class myProdData
    {
        public  Dictionary<string, myValue> Mapping { get; set; }
    }

    static void Main(string[] args)
    {
        var o = new mySystemPosition()
        {
            ProdData = new myProdData()
            {
                Mapping = new Dictionary<string, myValue>()
                {
                    {"123", new myValue() {Id = 1, Label = "Item1"}},
                    {"345", new myValue() {Id = 2, Label = "Item2"}},
                }
            }
        };

        var json = o.ToJson();
        Console.WriteLine(json);
        Console.ReadKey();
    }

Вот вывод консоли (просто хорошо отформатированный):

{
    "Text":null,
    "ProdData":{
        "Mapping":{
            "123":{
                "_id":1,
                "Label":"Item1"
            },
            "345":{
                "_id":2,
                "Label":"Item2"
            }
        }
    }
}

Вы можете проверить сериализацию, используя метод расширения ToJson(), чтобы увидеть, что все правильно, и после этого использовать ToBson() при необходимости.

...