Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
226 views
in Technique[技术] by (71.8m points)

mongodb - C# 10gen and mongo: deserialization for members as interfaces

All

Consider this example:

    private class CollectionHolder
    {
        public ObjectId Id { get; set; }
        public MyCollection Collection { get; set; }
    }

    private class MyCollection : List<int>
    {
        public MyCollection(List<int> a)
        {
            this.AddRange(a);
        }
    }

    private static void CollectionTest()
    {
        var collection = database.GetCollection<MyCollection>("collectionTest");
        collection.RemoveAll();
        collection.Save(new CollectionHolder { Collection = new MyCollection(new List<int> { 1, 2, 3, 4, 5 }) });
        var x = collection.AsQueryable().First(); //exception!
        x.ForEach(Console.WriteLine);
    }

The marked line throws exception

An error occurred while deserializing the Collection property of class MongoDriverTest.Program+CollectionHolder: An error occurred while deserializing the Capacity property of class MongoDriverTest.Program+MyCollection: Object reference not set to an instance of an object.

I am not sure, is this a bug in 10gen mongo driver, or is this impossible to implement? How do You think, should this be posted as a bug?

Moreover -- what is the best way to avoid such kind of errors?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem with custom collections in 1.4.2 and earlier is that since there is no serializer registered for your custom collection the C# driver attempts to serialize it using the BsonClassMapSerializer. But the BsonClassMapSerializer requires the class being serialized to expose all the data to be serialized as public get/set properties (which your base class List<T> does not).

The only thing that changes in 1.5 is how the driver chooses which serializer to use when a POCO implements IEnumerable or IDictionary.

You can use custom collections already in 1.4.2 and earlier by explicitly registering a serializer for your custom collection like this:

BsonSerializer.RegisterSerializer(typeof(MyCollection), new EnumerableSerializer<int>());

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...