/// <summary> /// Define a subdocument (or a list of) as a reference /// </summary> public EntityBuilder <T> DbRef <K>(Expression <Func <T, K> > property, string collectionName) { if (string.IsNullOrEmpty(collectionName)) { throw new ArgumentNullException("collectionName"); } return(this.GetProperty(property, (p) => { var typeRef = typeof(K); if (Reflection.IsList(typeRef)) { var itemType = typeRef.IsArray ? typeRef.GetElementType() : Reflection.UnderlyingTypeOf(typeRef); var mapper = _mapper.GetPropertyMapper(itemType); RegisterDbRefList(p, collectionName, typeRef, itemType, mapper); } else { var mapper = _mapper.GetPropertyMapper(typeRef); RegisterDbRef(p, collectionName, typeRef, mapper); } })); }
internal object Deserialize(Type type, BsonValue value) { Func <BsonValue, object> custom; // null value - null returns if (value.IsNull) { return(null); } // if is nullable, get underlying type else if (Reflection.IsNullable(type)) { type = Reflection.UnderlyingTypeOf(type); } // check if your type is already a BsonValue/BsonDocument/BsonArray if (type == typeof(BsonValue)) { return(new BsonValue(value)); } else if (type == typeof(BsonDocument)) { return(value.AsDocument); } else if (type == typeof(BsonArray)) { return(value.AsArray); } // raw values to native bson values else if (_bsonTypes.Contains(type)) { return(value.RawValue); } // simple ConvertTo to basic .NET types else if (_basicTypes.Contains(type)) { return(Convert.ChangeType(value.RawValue, type)); } // enum value is a string else if (type.IsEnum) { return(Enum.Parse(type, value.AsString)); } // test if has a custom type implementation else if (_customDeserializer.TryGetValue(type, out custom)) { return(custom(value)); } // if value is array, deserialize as array else if (value.IsArray) { if (type.IsArray) { return(this.DeserializeArray(type.GetElementType(), value.AsArray)); } else { return(this.DeserializeList(type, value.AsArray)); } } // if value is document, deserialize as document else if (value.IsDocument) { BsonValue typeField; var doc = value.AsDocument; // test if value is object and has _type if (doc.RawValue.TryGetValue("_type", out typeField)) { type = Type.GetType(typeField.AsString); } var o = Reflection.CreateInstance(type); if (o is IDictionary && type.IsGenericType) { var k = type.GetGenericArguments()[0]; var t = type.GetGenericArguments()[1]; this.DeserializeDictionary(k, t, (IDictionary)o, value.AsDocument); } else { this.DeserializeObject(type, o, doc); } return(o); } // in last case, return value as-is - can cause "cast error" // it's used for "public object MyInt { get; set; }" return(value.RawValue); }