Beispiel #1
0
        private ProjectionModification CreateMethodCallExpression(ParameterExpression parameter, List <IRelatedBinding> relatedBindings, List <IUnprojectedBinding> unprojectedBindings)
        {
            //We will create an AnonymousType(this type is part of AgileFx), to hold the new projection.
            var typeArgs = new List <Type>();

            typeArgs.Add(queryableType.NonPrimitiveEnumerableItemType.TranslatedType);
            relatedBindings.ForEach(binding => typeArgs.Add(binding.TranslatedType));
            var anonType = typeTranslationUtil.GetAnonymousType(typeArgs.ToArray());

            var ctor          = anonType.GetConstructor(Type.EmptyTypes);
            var newExpression = Expression.New(ctor);

            //Fields in the Projected Type
            var fieldsInProjectedType = new Dictionary <MemberInfo, SimpleType>();

            //The first field is the original type. This goes in as Field0.
            fieldsInProjectedType.Add(anonType.GetProperties()[0], queryableType.NonPrimitiveEnumerableItemType);

            var memberBindings = new List <MemberBinding>();

            //The first field is the original type. This goes in as Field0.
            memberBindings.Add(Expression.Bind(anonType.GetProperties()[0], parameter));

            int propCounter        = 1;
            var anonTypeProperties = anonType.GetProperties();

            foreach (var binding in relatedBindings)
            {
                var propInfo = anonTypeProperties[propCounter];

                memberBindings.Add(Expression.Bind(propInfo, binding.TranslatedExpression));
                fieldsInProjectedType.Add(propInfo, null);
                propCounter++;
            }

            var memberInit = Expression.MemberInit(newExpression, memberBindings);
            var lambda     = Expression.Lambda(memberInit, parameter);


            var projectedType = new ProjectedType(queryableType.NonPrimitiveEnumerableItemType.Type, anonType, ctor, null, fieldsInProjectedType,
                                                  relatedBindings, unprojectedBindings);

            Func <IQueryable <object>, Expression <Func <object, object> >, IQueryable <object> > f = Queryable.Select;
            var selectMethod = f.Method.GetGenericMethodDefinition().MakeGenericMethod(queryableType.NonPrimitiveEnumerableItemType.TranslatedType, anonType);
            var mce          = Expression.Call(null, selectMethod, currentExpression, lambda);

            return(new ProjectionModification {
                ModifiedExpression = mce, QueryableType = RuntimeTypes.CreateEnumerable(projectedType)
            });
        }