private IBsonSerializer BuildProjectedSerializer(ProjectionMapping mapping)
        {
            // We are building a serializer specifically for a projected type based
            // on serialization information collected from other serializers.
            // We cannot cache this in the serializer registry because the compiler reuses
            // the same anonymous type definition in different contexts as long as they
            // are structurally equatable. As such, it might be that two different queries
            // projecting the same shape might need to be deserialized differently.
            var classMap = BuildClassMap(mapping.Expression.Type, mapping);

            var mappedParameters = mapping.Members
                                   .Where(x => x.Parameter != null)
                                   .OrderBy(x => x.Parameter.Position)
                                   .Select(x => x.Member)
                                   .ToList();

            if (mappedParameters.Count > 0)
            {
                classMap.MapConstructor(mapping.Constructor)
                .SetArguments(mappedParameters);
            }

            var serializerType = typeof(BsonClassMapSerializer <>).MakeGenericType(mapping.Expression.Type);

            return((IBsonSerializer)Activator.CreateInstance(serializerType, classMap.Freeze()));
        }
        private IBsonSerializer BuildProjectedSerializer(ProjectionMapping mapping)
        {
            // We are building a serializer specifically for a projected type based
            // on serialization information collected from other serializers.
            // We cannot cache this in the serializer registry because the compiler reuses 
            // the same anonymous type definition in different contexts as long as they 
            // are structurally equatable. As such, it might be that two different queries 
            // projecting the same shape might need to be deserialized differently.
            var classMap = BuildClassMap(mapping.Expression.Type, mapping);

            var mappedParameters = mapping.Members
                .Where(x => x.Parameter != null)
                .OrderBy(x => x.Parameter.Position)
                .Select(x => x.Member)
                .ToList();

            if (mappedParameters.Count > 0)
            {
                classMap.MapConstructor(mapping.Constructor)
                    .SetArguments(mappedParameters);
            }

            var serializerType = typeof(BsonClassMapSerializer<>).MakeGenericType(mapping.Expression.Type);
            return (IBsonSerializer)Activator.CreateInstance(serializerType, classMap.Freeze());
        }
示例#3
0
        private IBsonSerializer BuildProjectedSerializer(ProjectionMapping mapping)
        {
            // We are building a serializer specifically for a projected type based
            // on serialization information collected from other serializers.
            // We cannot cache this in the serializer registry because the compiler reuses
            // the same anonymous type definition in different contexts as long as they
            // are structurally equatable. As such, it might be that two different queries
            // projecting the same shape might need to be deserialized differently.
            var          classMapType = typeof(BsonClassMap <>).MakeGenericType(mapping.Expression.Type);
            BsonClassMap classMap     = (BsonClassMap)Activator.CreateInstance(classMapType);

            foreach (var memberMapping in mapping.Members)
            {
                var serializationExpression = memberMapping.Expression as ISerializationExpression;
                if (serializationExpression == null)
                {
                    var serializer        = Build(memberMapping.Expression);
                    var serializationInfo = new BsonSerializationInfo(
                        memberMapping.Member.Name,
                        serializer,
                        GetMemberType(memberMapping.Member));
                    serializationExpression = new SerializationExpression(
                        memberMapping.Expression,
                        serializationInfo);
                }

                var memberMap = classMap.MapMember(memberMapping.Member)
                                .SetSerializer(serializationExpression.SerializationInfo.Serializer)
                                .SetElementName(memberMapping.Member.Name);

                if (classMap.IdMemberMap == null && serializationExpression is GroupIdExpression)
                {
                    classMap.SetIdMember(memberMap);
                }
            }

            var mappedParameters = mapping.Members
                                   .Where(x => x.Parameter != null)
                                   .OrderBy(x => x.Parameter.Position)
                                   .Select(x => x.Member)
                                   .ToList();

            if (mappedParameters.Count > 0)
            {
                classMap.MapConstructor(mapping.Constructor)
                .SetArguments(mappedParameters);
            }

            var serializerType = typeof(BsonClassMapSerializer <>).MakeGenericType(mapping.Expression.Type);

            return((IBsonSerializer)Activator.CreateInstance(serializerType, classMap.Freeze()));
        }
示例#4
0
        private BsonClassMap BuildClassMap(Type type, ProjectionMapping mapping)
        {
            if (type == null || type == typeof(object))
            {
                return(null);
            }

            var baseClassMap = BuildClassMap(type.BaseType, mapping);

            if (baseClassMap != null)
            {
                baseClassMap.Freeze();
            }
            var classMap = new BsonClassMap(type, baseClassMap);

            foreach (var memberMapping in mapping.Members.Where(x => x.Member.DeclaringType == type))
            {
                var serializationExpression = memberMapping.Expression as ISerializationExpression;
                if (serializationExpression == null)
                {
                    var serializer        = Build(memberMapping.Expression);
                    var serializationInfo = new BsonSerializationInfo(
                        memberMapping.Member.Name,
                        serializer,
                        GetMemberType(memberMapping.Member));
                    serializationExpression = new SerializationExpression(
                        memberMapping.Expression,
                        serializationInfo);
                }

                var memberMap = classMap.MapMember(memberMapping.Member)
                                .SetSerializer(serializationExpression.SerializationInfo.Serializer)
                                .SetElementName(memberMapping.Member.Name);

                if (classMap.IdMemberMap == null && serializationExpression is GroupIdExpression)
                {
                    classMap.SetIdMember(memberMap);
                }
            }

            return(classMap);
        }
示例#5
0
        private BsonClassMap BuildClassMap(Type type, ProjectionMapping mapping)
        {
            if (type == null || type == typeof(object))
            {
                return null;
            }

            var baseClassMap = BuildClassMap(type.GetTypeInfo().BaseType, mapping);
            if (baseClassMap != null)
            {
                baseClassMap.Freeze();
            }
            var classMap = new BsonClassMap(type, baseClassMap);

            foreach (var memberMapping in mapping.Members.Where(x => x.Member.DeclaringType == type))
            {
                var serializationExpression = memberMapping.Expression as SerializationExpression;
                if (serializationExpression == null)
                {
                    var serializer = Build(memberMapping.Expression);
                    serializationExpression = new FieldExpression(
                        memberMapping.Member.Name,
                        serializer,
                        memberMapping.Expression);
                }

                var memberMap = classMap.MapMember(memberMapping.Member)
                    .SetSerializer(serializationExpression.Serializer)
                    .SetElementName(memberMapping.Member.Name);

                if (classMap.IdMemberMap == null && serializationExpression is GroupingKeyExpression)
                {
                    classMap.SetIdMember(memberMap);
                }
            }

            return classMap;
        }
        private BsonValue TranslateMapping(ProjectionMapping mapping)
        {
            BsonDocument doc = new BsonDocument();
            bool hasId = false;
            foreach (var memberMapping in mapping.Members)
            {
                var value = TranslateValue(memberMapping.Expression);
                string name = memberMapping.Member.Name;
                if (!hasId && memberMapping.Expression is GroupingKeyExpression)
                {
                    name = "_id";
                    hasId = true;
                    doc.InsertAt(0, new BsonElement(name, value));
                }
                else
                {
                    doc.Add(name, value);
                }
            }

            return doc;
        }