Exemple #1
0
        public void Read_should_return_false_when_wrapped_reader_state_is_Done()
        {
            var document      = new BsonDocument();
            var wrappedReader = new BsonDocumentReader(document);
            var subject       = new BsonReaderAdapter(wrappedReader);

            subject.Read(); // StartObject
            subject.Read(); // EndObject
            wrappedReader.State.Should().Be(BsonReaderState.Done);

            var result = subject.Read();

            result.Should().BeFalse();
        }
        private object DeserializeKeyString(string keyString)
        {
            var keyDocument = new BsonDocument("k", keyString);

            using (var keyReader = new BsonDocumentReader(keyDocument))
            {
                var context = BsonDeserializationContext.CreateRoot(keyReader);
                keyReader.ReadStartDocument();
                keyReader.ReadName("k");
                var key = _keySerializer.Deserialize(context);
                keyReader.ReadEndDocument();
                return(key);
            }
        }
        /// <summary>
        /// Deserializes the value.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>The deserialized value.</returns>
        public object DeserializeValue(BsonValue value)
        {
            var tempDocument = new BsonDocument("value", value);

            using (var reader = new BsonDocumentReader(tempDocument))
            {
                var context = BsonDeserializationContext.CreateRoot(reader);
                reader.ReadStartDocument();
                reader.ReadName("value");
                var deserializedValue = _serializer.Deserialize(context);
                reader.ReadEndDocument();
                return(deserializedValue);
            }
        }
Exemple #4
0
        public void ReserializingStringIdEntityMaintainsStateExceptNulls()
        {
            var foreignProperty = EntityMapping.GetOrCreateDefinition(typeof(StringIdModel)).GetIdProperty();
            var serializer      = new EntityNavigationCollectionSerializer <StringIdModel>(foreignProperty);

            var initialCollection = new EntityNavigationCollection <StringIdModel>(foreignProperty)
            {
                new StringIdModel
                {
                    Description = "1"
                },
                new StringIdModel
                {
                    Id          = "5ac383379a5f1303784400f8",
                    Description = "2"
                }
            };
            EntityNavigationCollection <StringIdModel> deserializedCollection = null;

            initialCollection.AddForeignId("5ac383379a5f1303784400f9");

            var document = new BsonDocument();

            using (var writer = new BsonDocumentWriter(document))
            {
                writer.WriteStartDocument();
                writer.WriteName("Items");

                var context = BsonSerializationContext.CreateRoot(writer);
                serializer.Serialize(context, initialCollection);

                writer.WriteEndDocument();
            }

            using (var reader = new BsonDocumentReader(document))
            {
                reader.ReadBsonType();
                reader.ReadStartDocument();
                reader.ReadBsonType();
                reader.SkipName();

                var context = BsonDeserializationContext.CreateRoot(reader);
                deserializedCollection = serializer.Deserialize(context) as EntityNavigationCollection <StringIdModel>;
            }

            Assert.AreEqual(3, initialCollection.GetForeignIds().Count());
            Assert.AreEqual(2, deserializedCollection.GetForeignIds().Count());
            Assert.IsTrue(deserializedCollection.GetForeignIds().All(id => initialCollection.GetForeignIds().Contains(id)));
        }
Exemple #5
0
        public void TestEmbeddedDocument()
        {
            BsonDocument document = new BsonDocument
            {
                { "doc", new BsonDocument {
                      { "a", 1 }, { "b", 2 }
                  } }
            };

            using (var bsonReader = new BsonDocumentReader(document))
            {
                var rehydrated = DeserializeBsonDocument(bsonReader);
                Assert.True(document.Equals(rehydrated));
            }
        }
Exemple #6
0
        public void TestArray()
        {
            BsonDocument document = new BsonDocument
            {
                { "array", new BsonArray {
                      1, 2, 3
                  } }
            };

            using (var bsonReader = new BsonDocumentReader(document))
            {
                var rehydrated = DeserializeBsonDocument(bsonReader);
                Assert.True(document.Equals(rehydrated));
            }
        }
        // methods
        public InsertMessage <TDocument> ReadMessage()
        {
            var jsonReader      = CreateJsonReader();
            var messageContext  = BsonDeserializationContext.CreateRoot <BsonDocument>(jsonReader);
            var messageDocument = BsonDocumentSerializer.Instance.Deserialize(messageContext);

            var opcode = messageDocument["opcode"].AsString;

            if (opcode != "insert")
            {
                throw new FormatException("Opcode is not insert.");
            }

            var requestId       = messageDocument["requestId"].ToInt32();
            var databaseName    = messageDocument["database"].AsString;
            var collectionName  = messageDocument["collection"].AsString;
            var maxBatchCount   = messageDocument["maxBatchCount"].ToInt32();
            var maxMessageSize  = messageDocument["maxMessageSize"].ToInt32();
            var continueOnError = messageDocument["continueOnError"].ToBoolean();
            var documents       = messageDocument["documents"];

            if (documents.IsBsonNull)
            {
                throw new FormatException("InsertMessageJsonEncoder requires documents to not be null.");
            }

            var batch = new List <TDocument>();

            foreach (BsonDocument serializedDocument in documents.AsBsonArray)
            {
                using (var documentReader = new BsonDocumentReader(serializedDocument))
                {
                    var documentContext = BsonDeserializationContext.CreateRoot <TDocument>(documentReader);
                    var document        = _serializer.Deserialize(documentContext);
                    batch.Add(document);
                }
            }
            var documentSource = new BatchableSource <TDocument>(batch);

            return(new InsertMessage <TDocument>(
                       requestId,
                       new CollectionNamespace(databaseName, collectionName),
                       _serializer,
                       documentSource,
                       maxBatchCount,
                       maxMessageSize,
                       continueOnError));
        }
Exemple #8
0
        public void TestIsAtEndOfFile()
        {
            var expected = new BsonDocument("x", 1);

            using (var reader = new BsonDocumentReader(expected))
            {
                var count = 0;
                while (!reader.IsAtEndOfFile())
                {
                    var document = BsonSerializer.Deserialize <BsonDocument>(reader);
                    Assert.Equal(expected, document);
                    count++;
                }
                Assert.Equal(1, count);
            }
        }
        // public methods
        /// <summary>
        /// Gets an enumerator for the result objects.
        /// </summary>
        /// <returns>An enumerator for the result objects.</returns>
        public IEnumerator <TResult> GetEnumerator()
        {
            foreach (var value in _source)
            {
                var document = new BsonDocument("_v", value);
                using (var bsonReader = new BsonDocumentReader(document))
                {
                    var context = BsonDeserializationContext.CreateRoot(bsonReader);
                    bsonReader.ReadStartDocument();
                    bsonReader.ReadName("_v");
                    yield return((TResult)_serializationInfo.Serializer.Deserialize(context));

                    bsonReader.ReadEndDocument();
                }
            }
        }
Exemple #10
0
        public void ReserializingObjectIdIdEntityMaintainsState()
        {
            var foreignProperty = EntityMapping.GetOrCreateDefinition(typeof(ObjectIdIdModel)).GetIdProperty();
            var serializer      = new EntityNavigationCollectionSerializer <ObjectIdIdModel>(foreignProperty);

            var initialCollection = new EntityNavigationCollection <ObjectIdIdModel>(foreignProperty)
            {
                new ObjectIdIdModel
                {
                    Id          = ObjectId.GenerateNewId(),
                    Description = "1"
                }
            };
            EntityNavigationCollection <ObjectIdIdModel> deserializedCollection = null;

            initialCollection.AddForeignId(ObjectId.GenerateNewId());

            var document = new BsonDocument();

            using (var writer = new BsonDocumentWriter(document))
            {
                writer.WriteStartDocument();
                writer.WriteName("Items");

                var context = BsonSerializationContext.CreateRoot(writer);
                serializer.Serialize(context, initialCollection);

                writer.WriteEndDocument();
            }

            using (var reader = new BsonDocumentReader(document))
            {
                reader.ReadBsonType();
                reader.ReadStartDocument();
                reader.ReadBsonType();
                reader.SkipName();

                var context = BsonDeserializationContext.CreateRoot(reader);
                deserializedCollection = serializer.Deserialize(context) as EntityNavigationCollection <ObjectIdIdModel>;
            }

            Assert.AreEqual(2, initialCollection.GetForeignIds().Count());
            Assert.AreEqual(2, deserializedCollection.GetForeignIds().Count());
            Assert.IsTrue(initialCollection.GetForeignIds().All(id => deserializedCollection.GetForeignIds().Contains(id)));
        }
Exemple #11
0
        /// <inheritdoc/>
        public async Task <IReadOnlyList <IAsyncCursor <TDocument> > > ExecuteAsync(IReadBinding binding, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(binding, nameof(binding));

            using (EventContext.BeginOperation())
                using (var channelSource = await binding.GetReadChannelSourceAsync(cancellationToken).ConfigureAwait(false))
                {
                    var command   = CreateCommand();
                    var operation = new ReadCommandOperation <BsonDocument>(_collectionNamespace.DatabaseNamespace, command, BsonDocumentSerializer.Instance, _messageEncoderSettings);
                    var result    = await operation.ExecuteAsync(channelSource, binding.ReadPreference, cancellationToken).ConfigureAwait(false);

                    var cursors = new List <AsyncCursor <TDocument> >();

                    foreach (var cursorDocument in result["cursors"].AsBsonArray.Select(v => v["cursor"].AsBsonDocument))
                    {
                        var cursorId   = cursorDocument["id"].ToInt64();
                        var firstBatch = cursorDocument["firstBatch"].AsBsonArray.Select(v =>
                        {
                            var bsonDocument = (BsonDocument)v;
                            using (var reader = new BsonDocumentReader(bsonDocument))
                            {
                                var context  = BsonDeserializationContext.CreateRoot(reader);
                                var document = _serializer.Deserialize(context);
                                return(document);
                            }
                        })
                                         .ToList();

                        var cursor = new AsyncCursor <TDocument>(
                            channelSource.Fork(),
                            _collectionNamespace,
                            command,
                            firstBatch,
                            cursorId,
                            _batchSize ?? 0,
                            0, // limit
                            _serializer,
                            _messageEncoderSettings);

                        cursors.Add(cursor);
                    }

                    return(cursors);
                }
        }
Exemple #12
0
        public void SerializeICollectionCompatibleButIsntEntityNavigationCollection()
        {
            var serializer = new EntityNavigationCollectionSerializer <ObjectIdIdModel>("Id");

            var initialCollection = new List <ObjectIdIdModel>
            {
                new ObjectIdIdModel
                {
                    Id          = ObjectId.GenerateNewId(),
                    Description = "1"
                }
            };
            EntityNavigationCollection <ObjectIdIdModel> deserializedCollection = null;

            var document = new BsonDocument();

            using (var writer = new BsonDocumentWriter(document))
            {
                writer.WriteStartDocument();
                writer.WriteName("Items");

                var context = BsonSerializationContext.CreateRoot(writer);
                serializer.Serialize(context, initialCollection);

                writer.WriteEndDocument();
            }

            using (var reader = new BsonDocumentReader(document))
            {
                reader.ReadBsonType();
                reader.ReadStartDocument();
                reader.ReadBsonType();
                reader.SkipName();

                var context = BsonDeserializationContext.CreateRoot(reader);
                deserializedCollection = serializer.Deserialize(context) as EntityNavigationCollection <ObjectIdIdModel>;
            }

            Assert.AreEqual(1, initialCollection.Count());
            Assert.AreEqual(1, deserializedCollection.GetForeignIds().Count());
            Assert.IsTrue(initialCollection.Select(e => e.Id).All(id => deserializedCollection.GetForeignIds().Contains(id)));
        }
Exemple #13
0
        public void DeserializingInvalidTypeThrowsException()
        {
            var serializer = new EntityNavigationCollectionSerializer <StringIdModel>("Id");

            var document = new BsonDocument(new Dictionary <string, object>
            {
                { "Items", false }
            });

            using (var reader = new BsonDocumentReader(document))
            {
                reader.ReadBsonType();
                reader.ReadStartDocument();
                reader.ReadBsonType();
                reader.SkipName();

                var context = BsonDeserializationContext.CreateRoot(reader);
                serializer.Deserialize(context);
            }
        }
        public void Then_version_is_deserialized_correct()
        {
            // Arrange
            var document = new BsonDocument {
                { "version", "0.1.1" }
            };
            BsonDocumentReader reader = CreateVersionReader(document);

            BsonDeserializationContext context = BsonDeserializationContext.CreateRoot(reader);
            var args = new BsonDeserializationArgs {
                NominalType = typeof(DocumentVersion)
            };

            // Act
            DocumentVersion result = _serializer.Deserialize(context, args);

            // Assert
            result.Should().BeOfType <DocumentVersion>();
            result.Should().Be("0.1.1");
        }
Exemple #15
0
        public void DeserializingInvalidTypeThrowsException()
        {
            var foreignProperty = EntityMapping.GetOrCreateDefinition(typeof(StringIdModel)).GetIdProperty();
            var serializer      = new EntityNavigationCollectionSerializer <StringIdModel>(foreignProperty);

            var document = new BsonDocument(new Dictionary <string, object>
            {
                { "Items", false }
            });

            using (var reader = new BsonDocumentReader(document))
            {
                reader.ReadBsonType();
                reader.ReadStartDocument();
                reader.ReadBsonType();
                reader.SkipName();

                var context = BsonDeserializationContext.CreateRoot(reader);
                serializer.Deserialize(context);
            }
        }
Exemple #16
0
        private IReadOnlyList <IAsyncCursor <TDocument> > CreateCursors(IChannelSourceHandle channelSource, BsonDocument command, BsonDocument result)
        {
            var cursors = new List <AsyncCursor <TDocument> >();

            using (var getMoreChannelSource = new ChannelSourceHandle(new ServerChannelSource(channelSource.Server, channelSource.Session.Fork())))
            {
                foreach (var cursorDocument in result["cursors"].AsBsonArray.Select(v => v["cursor"].AsBsonDocument))
                {
                    var cursorId   = cursorDocument["id"].ToInt64();
                    var firstBatch = cursorDocument["firstBatch"].AsBsonArray.Select(v =>
                    {
                        var bsonDocument = (BsonDocument)v;
                        using (var reader = new BsonDocumentReader(bsonDocument))
                        {
                            var context  = BsonDeserializationContext.CreateRoot(reader);
                            var document = _serializer.Deserialize(context);
                            return(document);
                        }
                    })
                                     .ToList();

                    // it's not affected by loadbalancing logic since it was deprecated in server version 4.1.
                    var cursor = new AsyncCursor <TDocument>(
                        getMoreChannelSource.Fork(),
                        _collectionNamespace,
                        command,
                        firstBatch,
                        cursorId,
                        _batchSize ?? 0,
                        0, // limit
                        _serializer,
                        _messageEncoderSettings);

                    cursors.Add(cursor);
                }
            }

            return(cursors);
        }
Exemple #17
0
        public void DeserializingNullReturnsCollection()
        {
            var serializer = new EntityNavigationCollectionSerializer <StringIdModel>("Id");

            var document = new BsonDocument(new Dictionary <string, object>
            {
                { "Items", null }
            });

            using (var reader = new BsonDocumentReader(document))
            {
                reader.ReadBsonType();
                reader.ReadStartDocument();
                reader.ReadBsonType();
                reader.SkipName();

                var context = BsonDeserializationContext.CreateRoot(reader);
                var result  = serializer.Deserialize(context);

                Assert.IsNotNull(result);
                Assert.IsInstanceOfType(result, typeof(EntityNavigationCollection <StringIdModel>));
            }
        }
Exemple #18
0
        public static UpdateDefinition <TEntity> Set <TEntity>(this UpdateDefinition <TEntity> definition, string fieldName, BsonValue value) where TEntity : class
        {
            var dotNetValue = BsonTypeMapper.MapToDotNetValue(value);
            var valueType   = dotNetValue?.GetType();

            IEntityProperty propertyDefinition = null;

            if (EntityMapping.IsValidTypeToMap(typeof(TEntity)))
            {
                propertyDefinition = EntityMapping.GetOrCreateDefinition(typeof(TEntity))
                                     .TraverseProperties()
                                     .Where(p => p.FullPath == fieldName)
                                     .FirstOrDefault();
            }

            var propertyType = propertyDefinition?.PropertyType;

            if (valueType == null && propertyType == null)
            {
                //For null values - they don't have any type data associated
                valueType = typeof(object);
            }
            else if (valueType == null || (propertyType != null && valueType != propertyType))
            {
                //Where BsonTypeMapper can't determine the type or it is a mismatch to what is set in the entity definition
                //The preference is on the definition type and the serializer on the specific member
                valueType = propertyType;

                //We will need the serializer defined for the specific member
                //Not all serializers will be registered (eg. EntityNavigationSerializer) so we need to look it up manually
                var declaringClassMap = BsonClassMap.LookupClassMap(propertyDefinition.EntityType);
                var memberMap         = declaringClassMap.GetMemberMapForElement(propertyDefinition.ElementName);
                var serializer        = memberMap.GetSerializer();

                //To prevent re-serializing back to a string, we use the BsonDocumentReader over JsonReader
                //Using BsonDocumentReader means the root must be a BsonDocument. Because the value may be a BsonArray, we need to wrap the value.
                var containerDocument = new BsonDocument
                {
                    { "Value", value }
                };

                using (var reader = new BsonDocumentReader(containerDocument))
                {
                    //Get the reader into a state where the serializer is starting on the right element
                    reader.ReadBsonType();
                    reader.ReadStartDocument();
                    reader.ReadBsonType();
                    reader.SkipName();

                    var context = BsonDeserializationContext.CreateRoot(reader);
                    dotNetValue = serializer.Deserialize(context);
                }
            }

            var typeArgs = new[] { typeof(TEntity), valueType };

            var specificDefinitionType = typeof(StringFieldDefinition <,>).MakeGenericType(typeArgs);
            var specificDefinition     = Activator.CreateInstance(specificDefinitionType, fieldName, null);         //ie. StringFieldDefintion<TEntity, valueType>

            foreach (var method in typeof(UpdateDefinitionExtensions).GetMethods(BindingFlags.NonPublic | BindingFlags.Static))
            {
                if (method.Name == nameof(InternalSet))
                {
                    var internalSetMethod = method.MakeGenericMethod(typeArgs);
                    var result            = internalSetMethod.Invoke(null, new[] { definition, specificDefinition, dotNetValue });
                    return(result as UpdateDefinition <TEntity>);
                }
            }

            return(default);
        public static UpdateDefinition <TEntity> Set <TEntity>(this UpdateDefinition <TEntity> definition, string fieldName, BsonValue value)
        {
            var dotNetValue        = BsonTypeMapper.MapToDotNetValue(value);
            var valueType          = dotNetValue?.GetType();
            var reflectedProperty  = typeof(TEntity).GetNestedProperty(fieldName);
            var reflectedValueType = reflectedProperty?.PropertyType;

            if (valueType == null && reflectedValueType == null)
            {
                //For null values - they don't have any type data associated
                valueType = typeof(object);
            }
            else if (valueType == null || (reflectedValueType != null && valueType != reflectedValueType))
            {
                //Where BsonTypeMapper can't determine the type or it is a mismatch to what is reflected from the type
                //The preference is on the reflected type and the serializer on the specific member
                valueType = reflectedValueType;

                //We will need the serializer defined for the specific member
                //Not all serializers will be registered (eg. EntityNavigationSerializer) so we need to look it up manually
                var declaringClassMap = BsonClassMap.LookupClassMap(reflectedProperty.DeclaringType);
                var memberMap         = declaringClassMap.GetMemberMap(reflectedProperty.Name);
                var serializer        = memberMap.GetSerializer();

                //To prevent re-serializing back to a string, we use the BsonDocumentReader over JsonReader
                //Using BsonDocumentReader means the root must be a BsonDocument. Because the value may be a BsonArray, we need to wrap the value.
                var containerDocument = new BsonDocument
                {
                    { "Value", value }
                };

                using (var reader = new BsonDocumentReader(containerDocument))
                {
                    //Get the reader into a state where the serializer is starting on the right element
                    reader.ReadBsonType();
                    reader.ReadStartDocument();
                    reader.ReadBsonType();
                    reader.SkipName();

                    var context = BsonDeserializationContext.CreateRoot(reader);
                    dotNetValue = serializer.Deserialize(context);
                }
            }

            var typeArgs = new[] { typeof(TEntity), valueType };

            var specificDefinitionType = typeof(StringFieldDefinition <,>).MakeGenericType(typeArgs);
            var specificDefinition     = Activator.CreateInstance(specificDefinitionType, fieldName, null);         //ie. StringFieldDefintion<TEntity, valueType>

            var expressionType = typeof(Expression);
            var setMethod      = typeof(MongoDB.Driver.UpdateDefinitionExtensions)
                                 .GetMethods()
                                 .Where(m => m.Name == "Set" && !m.GetParameters().Any(p => expressionType.IsAssignableFrom(p.ParameterType)))
                                 .FirstOrDefault()
                                 .MakeGenericMethod(typeArgs);

            //Breaking down the above reflection, we are trying to get the "Set" method that doesn't take an "Expression" as a parameter
            //The method we want takes an `UpdateDefinition`, `FieldDefinition` and `Value` as the 3 parameters
            //Accounting for the variables and types, the method call would look something, something like the following
            //MongoDB.Driver.UpdateDefinitionExtensions.Set<TEntity, TField>(UpdateDefinition<TEntity> definition, StringFieldDefinition<TEntity, TField> specificDefinition, dotNetValue)

            var result = setMethod.Invoke(null, new[] { definition, specificDefinition, dotNetValue });

            return(result as UpdateDefinition <TEntity>);
        }
Exemple #20
0
        // methods
        public ReplyMessage <TDocument> ReadMessage()
        {
            if (_jsonReader == null)
            {
                throw new InvalidOperationException("No jsonReader was provided.");
            }

            var messageContext  = BsonDeserializationContext.CreateRoot <BsonDocument>(_jsonReader);
            var messageDocument = BsonDocumentSerializer.Instance.Deserialize(messageContext);

            var opcode = messageDocument["opcode"].AsString;

            if (opcode != "reply")
            {
                throw new FormatException("Opcode is not reply.");
            }

            var awaitCapable   = messageDocument.GetValue("awaitCapable", false).ToBoolean();
            var cursorId       = messageDocument["cursorId"].ToInt64();
            var cursorNotFound = messageDocument.GetValue("cursorNotFound", false).ToBoolean();
            var numberReturned = messageDocument["numberReturned"].ToInt32();
            var queryFailure   = false;
            var requestId      = messageDocument["requestId"].ToInt32();
            var responseTo     = messageDocument["responseTo"].ToInt32();
            var startingFrom   = messageDocument.GetValue("startingFrom", 0).ToInt32();

            List <TDocument> documents = null;

            if (messageDocument.Contains("documents"))
            {
                documents = new List <TDocument>();
                foreach (BsonDocument serializedDocument in messageDocument["documents"].AsBsonArray)
                {
                    using (var documentReader = new BsonDocumentReader(serializedDocument))
                    {
                        var documentContext = BsonDeserializationContext.CreateRoot <TDocument>(documentReader);
                        var document        = _serializer.Deserialize(documentContext);
                        documents.Add(document);
                    }
                }
            }

            BsonDocument queryFailureDocument = null;

            if (messageDocument.Contains("queryFailure"))
            {
                queryFailure         = true;
                queryFailureDocument = messageDocument["queryFailure"].AsBsonDocument;
            }

            return(new ReplyMessage <TDocument>(
                       awaitCapable,
                       cursorId,
                       cursorNotFound,
                       documents,
                       numberReturned,
                       queryFailure,
                       queryFailureDocument,
                       requestId,
                       responseTo,
                       _serializer,
                       startingFrom));
        }
 private static T DeserializeBson <T>(ContractTypeSerializer serializer, BsonDocument bson)
 {
     using var reader = new BsonDocumentReader(bson);
     return((T)serializer.Deserialize <ICommandMessage>(
                new MongoReaderAdapter(reader)));
 }
Exemple #22
0
        private async Task <IEnumerable <T> > Find <T>(ObjectSerializer Serializer, IMongoCollection <BsonDocument> Collection,
                                                       int Offset, int MaxCount, FilterDefinition <BsonDocument> BsonFilter, params string[] SortOrder)
        {
            IFindFluent <BsonDocument, BsonDocument> ResultSet = Collection.Find <BsonDocument>(BsonFilter);

            if (SortOrder.Length > 0)
            {
                SortDefinition <BsonDocument> SortDefinition = null;

                foreach (string SortBy in SortOrder)
                {
                    if (SortDefinition == null)
                    {
                        if (SortBy.StartsWith("-"))
                        {
                            SortDefinition = Builders <BsonDocument> .Sort.Descending(Serializer.ToShortName(SortBy.Substring(1)));
                        }
                        else
                        {
                            SortDefinition = Builders <BsonDocument> .Sort.Ascending(Serializer.ToShortName(SortBy));
                        }
                    }
                    else
                    {
                        if (SortBy.StartsWith("-"))
                        {
                            SortDefinition = SortDefinition.Descending(Serializer.ToShortName(SortBy.Substring(1)));
                        }
                        else
                        {
                            SortDefinition = SortDefinition.Ascending(Serializer.ToShortName(SortBy));
                        }
                    }
                }

                ResultSet = ResultSet.Sort(SortDefinition);
            }

            if (Offset > 0)
            {
                ResultSet = ResultSet.Skip(Offset);
            }

            if (MaxCount < int.MaxValue)
            {
                ResultSet = ResultSet.Limit(MaxCount);
            }

            IAsyncCursor <BsonDocument> Cursor = await ResultSet.ToCursorAsync();

            LinkedList <T>          Result = new LinkedList <T>();
            BsonDeserializationArgs Args   = new BsonDeserializationArgs()
            {
                NominalType = typeof(T)
            };

            while (await Cursor.MoveNextAsync())
            {
                foreach (BsonDocument Document in Cursor.Current)
                {
                    BsonDocumentReader         Reader  = new BsonDocumentReader(Document);
                    BsonDeserializationContext Context = BsonDeserializationContext.CreateRoot(Reader);

                    T Obj = (T)Serializer.Deserialize(Context, Args);
                    Result.AddLast(Obj);
                }
            }

            return(Result);
        }