private void AddInclude(SimpleType source, MemberExpression memberSelector, LambdaExpression collectionInclude) { var members = source.GetAllMembers(); if (members.Count > 0 && memberSelector.GetDepth() > 1) { var innermostMember = ExpressionUtil.GetInnermostMemberExpression(memberSelector); foreach (var kvp in members) { if (kvp.Key == innermostMember.Member) { AddInclude(kvp.Value, ExpressionUtil.ReplaceInnermostMemberExpressionWithParameter(memberSelector) as MemberExpression, collectionInclude); return; } } } else { var parameter = ExpressionUtil.GetParameterExpression(memberSelector); if (collectionInclude != null) { source.Includes.Add(IncludeDirectiveUtil.GetIncludeInCollectionDirective(memberSelector, collectionInclude)); } else { source.Includes.Add(IncludeDirectiveUtil.GetIncludeDirective(memberSelector)); } } }
private List <QueryBinding> GetQueryBindings(SimpleType qType, Expression inner) { var result = new List <QueryBinding>(); //Create a binding which wraps the queryable type. var queryBinding = new QueryBinding { Value = qType, TranslatedExpression = inner }; result.Add(queryBinding); //If this is a complex type, we need to recursively go through the fields. //eg of complex type is: new { U = user, A = user.Account } // We are trying to traverse U and A in the example above. var members = qType.GetAllMembers(); if (members.Count > 0) { foreach (var kvp in members) { result.AddRange(GetQueryBindings(kvp.Value, typeTranslationUtil.GetTranslatedMemberExpression(qType.Type, qType.GetMemberName(kvp.Key), inner))); } } return(result); }
//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; }); }
private Func <object, object> Get_FindValueInTreeMatchingTrackedType_Computation(SimpleType sourceType, SimpleType trackedType) { if (sourceType == trackedType) { return(tableEntity => tableEntity); } foreach (var kvp in sourceType.GetAllMembers()) { var memberGetter = Get_FindValueInTreeMatchingTrackedType_Computation(kvp.Value, trackedType); if (memberGetter != null) { var translatedValueGetter = sourceType.GetTranslatedMemberValue(kvp.Key, entityContext._InternalServices.TypeTranslationUtil); return(tableEntity => memberGetter(translatedValueGetter(tableEntity))); } } if (sourceType.NonPrimitiveEnumerableItemType != null) { var collectionItemGetter = Get_FindValueInTreeMatchingTrackedType_Computation(sourceType.NonPrimitiveEnumerableItemType, trackedType); if (collectionItemGetter != null) { return(tableEntity => { var list = new List <object>(); foreach (var item in (tableEntity as IEnumerable)) { list.Add(collectionItemGetter(item)); } return list; }); } } return(null); }