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()); }
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())); }
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); }
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; }