public Dictionary <MemberInfo, SimpleType> GetAllMembers() { if (TypesUtil.IsCompilerGeneratedAnonymousType(Type)) { var properties = Type.GetProperties(); var dic = new Dictionary <MemberInfo, SimpleType>(); for (int i = 0; i < properties.Length; i++) { dic.Add(properties[i], ConstructorArgs[i]); } return(dic); } else { return(Fields); } }
//Where the user has mentioned a specific constructor in the query. private Func <object, TableEntityRow, object> Get_CreateTypeWithConstructor_Computation(SimpleType trackedType, MaterializationData data) { var fields = new Dictionary <MemberInfo, KeyValuePair <Func <object, object>, Func <object, TableEntityRow, object> > >(); var constructorArgs = new Dictionary <MemberInfo, KeyValuePair <Func <object, object>, Func <object, TableEntityRow, object> > >(); if (TypesUtil.IsCompilerGeneratedAnonymousType(trackedType.Type)) { constructorArgs = Get_GetMembers_Computation(trackedType.GetAllMembers(), trackedType, data); } else { fields = Get_GetMembers_Computation(trackedType.Fields, trackedType, data); } Action <object, object, TableEntityRow> setCollectionItems = (newObj, projectedEntity, source) => { }; if (trackedType.NonPrimitiveEnumerableItemType != null) { var getOrCreateCollectionItem = Get_GetOrCreateEntityOrCollection_Computation(trackedType.NonPrimitiveEnumerableItemType, data); var addMethod = trackedType.Constructor.DeclaringType.GetMethod("Add", new Type[] { trackedType.NonPrimitiveEnumerableItemType.Type }); setCollectionItems = (newObj, projectedEntity, source) => { foreach (var tableCollectionItem in (projectedEntity as IEnumerable)) { var collItem = getOrCreateCollectionItem(tableCollectionItem, source); addMethod.Invoke(newObj, new object[] { collItem }); } }; } Action <object, MemberInfo, object> setMemberValue = (obj, m, val) => trackedType.Constructor.DeclaringType.GetProperty(m.Name).SetValue(obj, val); return((projectedEntity, source) => { var args = constructorArgs.Select(kvp => kvp.Value.Value(kvp.Value.Key(projectedEntity), source)).ToArray(); var newObj = trackedType.Constructor.Invoke(args); foreach (var fld in fields) { setMemberValue(newObj, fld.Key, fld.Value.Value(fld.Value.Key(projectedEntity), source)); } setCollectionItems(newObj, projectedEntity, source); return newObj; }); }
//Serialization of entities should consider the included fields. // - If A.B is defined as an include on A at the time of materialization, B should also be serialized // and re-attached when A is deserialized. private SerializableObjectGraph CreateObjectGraph(object entity) { var sourceType = entity.GetType(); //If this is a collection, create a graph for each item in the collection. if (TypesUtil.IsNonPrimitiveCollection(sourceType)) { var list = new List <IObjectGraph>(); foreach (object obj in entity as IEnumerable) { list.Add(CreateObjectGraph(obj)); } return(new SerializableCollection { Collection = list, InstanceType = sourceType }); } else { var serializableInstance = new SerializableInstance { Object = entity, InstanceType = entity.GetType() }; if (entity is IEntity) { var materializationIncludes = GetIncludeExpressions((entity as IEntity)._getIntermediateEntity().IncludeDirectives); foreach (var includeExps in materializationIncludes) { AddIncludes(serializableInstance, includeExps.FieldChain, includeExps.IncludesInCollection); } } else { if (TypesUtil.IsCompilerGeneratedAnonymousType(sourceType)) { serializableInstance.Object = null; serializableInstance.InstanceType = sourceType; } var properties = (entity is IEntity) ? sourceType.GetProperties() .Where(p => typeof(IEntity).IsAssignableFrom(p.PropertyType) || typeof(IEntityCollection).IsAssignableFrom(p.PropertyType)).ToArray() : (TypesUtil.IsPrimitiveDataType(sourceType) || sourceType.IsArray || TypesUtil.IsNonPrimitiveCollection(sourceType) ? new PropertyInfo[] {} : sourceType.GetProperties()); foreach (var prop in properties) { var propVal = prop.GetValue(entity, null); //Primitive types can be stored as is. if (TypesUtil.IsPrimitiveDataType(prop.PropertyType)) { serializableInstance.IncludedMembers.Add ( prop, new SerializableInstance { Object = propVal, InstanceType = prop.PropertyType } ); continue; } //This is a single object (possibly an entity); but not a primitive type or a collection if (!TypesUtil.IsNonPrimitiveCollection(prop.PropertyType)) { serializableInstance.IncludedMembers.Add ( prop, CreateObjectGraph(propVal) ); } //Collection of non-primitive types else if (TypesUtil.IsNonPrimitiveCollection(prop.PropertyType)) { var itemsInCollection = new List <IObjectGraph>(); foreach (var item in (propVal as IEnumerable)) { itemsInCollection.Add(CreateObjectGraph(item)); } serializableInstance.IncludedMembers.Add ( prop, new SerializableCollection { Collection = itemsInCollection, InstanceType = prop.PropertyType } ); } } } return(serializableInstance); } }