예제 #1
0
        public void NullDeserialization()
        {
            EntityMapping.AddMappingProcessor(new TypeDiscoveryProcessor());
            EntityMapping.RegisterType(typeof(KnownBaseModel));

            var serializer = TypeDiscoverySerializationProvider.Instance.GetSerializer(typeof(KnownBaseModel));

            var document = new BsonDocument
            {
                { "Item", BsonNull.Value }
            };

            KnownBaseModel deserializedResult;

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

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

            Assert.IsNull(deserializedResult);
        }
        public void NullDeserialization()
        {
            var entityMapper = new EntityMapper <KnownBaseModel>();
            var serializer   = TypeDiscoverySerializationProvider.Instance.GetSerializer(typeof(KnownBaseModel));

            var document = new BsonDocument
            {
                { "Item", BsonNull.Value }
            };

            KnownBaseModel deserializedResult;

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

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

            Assert.AreEqual(null, deserializedResult);
        }
예제 #3
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)));
        }
예제 #4
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)));
        }
예제 #5
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)));
        }
예제 #6
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);
            }
        }
예제 #7
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);
            }
        }
예제 #8
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>));
            }
        }
        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>);
        }
예제 #10
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);