示例#1
0
            public override Expression Translate(MethodCallExpression mce, Expression translatedSource, IEnumerable <Expression> otherArgs, QueryAnalysisContext context)
            {
                var  _otherArgs  = otherArgs.ToArray();
                bool isQueryable = DefinedOnQueryable(mce);

                //Func<TSource, int, IEnumerable<TCollection>>
                var collectionSelectorTranslation = TranslateLambdaToIEnumerableFormat(_otherArgs[0],
                                                                                       new[]   { context.QueryableType.NonPrimitiveEnumerableItemType, //TSource
                                                                                                 new SimpleType(typeof(int)) },                        //int
                                                                                       context, isQueryable);

                //Func<TSource, TCollection, TResult>
                var resultSelectorTranslation = QueryTranslationVisitor.TranslateLambda(_otherArgs[1],
                                                                                        new[] { context.QueryableType.NonPrimitiveEnumerableItemType,                         //TSource
                                                                                                collectionSelectorTranslation.QueryableType.NonPrimitiveEnumerableItemType }, //TCollection
                                                                                        context, isQueryable);

                var newArgs = new Expression[]
                {
                    translatedSource,
                    collectionSelectorTranslation.TranslatedExpression
                };

                //SelectMany<TSource, TCollection, TResult>
                var translatedMethod = mce.Method.GetGenericMethodDefinition().MakeGenericMethod(
                    context.QueryableType.NonPrimitiveEnumerableItemType.TranslatedType,
                    collectionSelectorTranslation.QueryableType.NonPrimitiveEnumerableItemType.TranslatedType,
                    resultSelectorTranslation.QueryableType.TranslatedType);

                //IEnumerable<TResult>
                context.QueryableType = RuntimeTypes.CreateEnumerable(resultSelectorTranslation.QueryableType);

                return(Expression.Call(mce.Object, translatedMethod, newArgs) as Expression);
            }
示例#2
0
            public override Expression Translate(MethodCallExpression mce, Expression translatedSource, IEnumerable <Expression> otherArgs, QueryAnalysisContext context)
            {
                var  _otherArgs  = otherArgs.ToArray();
                bool isQueryable = DefinedOnQueryable(mce);

                //Func<TSource, TKey>
                var keySelectorTranslation = QueryTranslationVisitor.TranslateLambda(_otherArgs[0], new[] { context.QueryableType.NonPrimitiveEnumerableItemType }, context, isQueryable);

                //Func<TKey, IEnumerable<TSource>, TResult>
                var resultSelectorTranslation = QueryTranslationVisitor.TranslateLambda(_otherArgs[1], new[] { keySelectorTranslation.QueryableType, context.QueryableType }, context, isQueryable);

                var newArgs = new Expression[]
                {
                    translatedSource,
                    keySelectorTranslation.TranslatedExpression,
                    resultSelectorTranslation.TranslatedExpression
                };

                //GroupBy2<TSource, TKey, TResult>
                var translatedMethod = mce.Method.GetGenericMethodDefinition().MakeGenericMethod(
                    context.QueryableType.NonPrimitiveEnumerableItemType.TranslatedType,
                    keySelectorTranslation.QueryableType.TranslatedType,
                    resultSelectorTranslation.QueryableType.TranslatedType);

                //IQueryable<TResult>
                context.QueryableType = RuntimeTypes.CreateEnumerable(resultSelectorTranslation.QueryableType);

                return(Expression.Call(mce.Object, translatedMethod, newArgs));
            }
示例#3
0
            public override Expression Translate(MethodCallExpression mce, Expression translatedSource, IEnumerable <Expression> otherArgs, QueryAnalysisContext context)
            {
                bool isQueryable = DefinedOnQueryable(mce);

                //Expression<Func<TSource, int, IEnumerable<TResult>>
                var selectorTranslation = TranslateLambdaToIEnumerableFormat(otherArgs.First(),
                                                                             new[] { context.QueryableType.NonPrimitiveEnumerableItemType,
                                                                                     new SimpleType(typeof(int)) },
                                                                             context, isQueryable);

                var newArgs = new Expression[]
                {
                    translatedSource,
                    selectorTranslation.TranslatedExpression
                };

                //SelectMany<TSource, TResult>
                var translatedMethod = mce.Method.GetGenericMethodDefinition().MakeGenericMethod(
                    context.QueryableType.NonPrimitiveEnumerableItemType.TranslatedType,
                    selectorTranslation.QueryableType.NonPrimitiveEnumerableItemType.TranslatedType);

                context.QueryableType = RuntimeTypes.CreateEnumerable(selectorTranslation.QueryableType.NonPrimitiveEnumerableItemType);

                return(Expression.Call(mce.Object, translatedMethod, newArgs) as Expression);
            }
示例#4
0
            public override Expression Translate(MethodCallExpression mce, Expression translatedSource, IEnumerable <Expression> otherArgs, QueryAnalysisContext context)
            {
                bool isQueryable = DefinedOnQueryable(mce);

                //Func<TSource, TKey>
                var keySelectorTranslation = QueryTranslationVisitor.TranslateLambda(otherArgs.First(),
                                                                                     new[] { context.QueryableType.NonPrimitiveEnumerableItemType }, context, isQueryable);

                var newArgs = new Expression[]
                {
                    translatedSource,
                    keySelectorTranslation.TranslatedExpression
                };

                //GroupBy<TSource, TKey>
                var translatedMethod = mce.Method.GetGenericMethodDefinition().MakeGenericMethod(
                    context.QueryableType.NonPrimitiveEnumerableItemType.TranslatedType,
                    keySelectorTranslation.QueryableType.TranslatedType);

                //IQueryable<IGrouping<TKey, TSource>>
                var groupingType  = RuntimeTypes.CreateGrouping(keySelectorTranslation.QueryableType, context.QueryableType.NonPrimitiveEnumerableItemType);
                var queryableType = RuntimeTypes.CreateEnumerable(groupingType);

                context.QueryableType = queryableType;

                return(Expression.Call(mce.Object, translatedMethod, newArgs));
            }
        public static IQueryable SelectByInterface <T>(this IQueryable <T> source, Type interfaceType, bool includeTypeName = true)
        {
            var properties = interfaceType.GetPublicProperties().Where(each => each.PropertyType.IsSimple()).ToList();

            var objectFields = properties.Select(each => each.Name).ToList();

            if (includeTypeName)
            {
                objectFields.Add("_Type");
            }

            var sourceType = source.GetType().GetGenericArguments().First();

            var param       = Expression.Parameter(sourceType);
            var expressions = new List <MemberBinding>();

            lock (RuntimeTypes) {
                if (!RuntimeTypes.ContainsKey(interfaceType))
                {
                    var runtimeType = new RuntimeObjectBuilder().CreateNewObject(interfaceType, interfaceType, objectFields.ToArray()).GetType();
                    RuntimeTypes.Add(interfaceType, runtimeType);
                }

                var instance = Activator.CreateInstance(RuntimeTypes[interfaceType]);
                var type     = instance.GetType();

                if (includeTypeName)
                {
                    var typeProperty = type.GetProperty("_Type");
                    expressions.Add(Expression.Bind(typeProperty, Expression.Constant(typeof(T).Name)));
                }

                foreach (var property in instance.GetType().GetProperties())
                {
                    if (property.Name.StartsWith("_"))
                    {
                        continue;
                    }

                    expressions.Add(Expression.Bind(property, Expression.PropertyOrField(param, property.Name)));
                }

                var init = Expression.MemberInit(Expression.New(instance.GetType()), expressions.ToArray());

                var func          = typeof(Func <,>).MakeGenericType(typeof(T), type);
                var lambdaMethods = typeof(Expression).GetMethods().Where(each => each.Name == "Lambda");

                var expression = lambdaMethods.First().MakeGenericMethod(func).Invoke(null, new object[] { init, new[] { param } }) as Expression;

                //var expression = Expression.Lambda<Func<T, I>>(init, param);
                var methods = typeof(Queryable).GetMethods().Where(each => each.Name == "Select").ToList();
                var method  = methods.FirstOrDefault().MakeGenericMethod(typeof(T), type);

                return(method.Invoke(null, new object[] { source, expression }) as IQueryable);
            }
        }
示例#6
0
 private SimpleType GetQueryableType(Type originalType, Type translatedType)
 {
     if (!TypesUtil.IsNonPrimitiveCollection(originalType))
     {
         return(new SimpleType(originalType, translatedType));
     }
     else
     {
         var itemType           = TypesUtil.GetGenericArgumentForBaseType(originalType, typeof(IEnumerable <>));
         var translatedItemType = TypesUtil.GetGenericArgumentForBaseType(translatedType, typeof(IEnumerable <>));
         return(RuntimeTypes.CreateEnumerable(new SimpleType(itemType, translatedItemType)));
     }
 }
示例#7
0
            public override Expression Translate(MethodCallExpression mce, Expression translatedFirstArg, IEnumerable <Expression> otherArgs, QueryAnalysisContext context)
            {
                //entityContext.CreateQuery<TSource>. We should turn this into tableContext.GetTable<TranslatedSource>
                var genericArg           = mce.Method.GetGenericArguments().First();
                var translatedGenericArg = context.TypeTranslationUtil.GetTranslatedType(genericArg);

                context.QueryableType = RuntimeTypes.CreateEnumerable(new SimpleType(genericArg, translatedGenericArg));

                //We cannot use the same mce.Method like we usually do, since the method itself should change (not just generic args)
                //  EntityContext.CreateQuery should be converted to LinqContext.GetTable.
                return(context.TypeTranslationUtil.GetTranslatedGenericMethodCall(translatedFirstArg, mce.Method,
                                                                                  new Type[] { translatedGenericArg }, new Expression[] { }));
            }
示例#8
0
            public override Expression Translate(MethodCallExpression mce, Expression translatedSource, IEnumerable <Expression> otherArgs, QueryAnalysisContext context)
            {
                bool isQueryable = DefinedOnQueryable(mce);

                //Func<TSource, IEnumerable<TResult>>
                var selectorTranslation = TranslateLambdaToIEnumerableFormat(otherArgs.First(),
                                                                             new[] { context.QueryableType.NonPrimitiveEnumerableItemType }, context, isQueryable);

                //Handling Many-to-Many Case.. Converting to SelectMany3 case
                if (selectorTranslation.QueryableType.NonPrimitiveEnumerableItemType is ManyToManyMapType)
                {
                    var mapType = selectorTranslation.QueryableType.NonPrimitiveEnumerableItemType as ManyToManyMapType;

                    var sourceTypeParam    = context.QueryableType.NonPrimitiveEnumerableItemType.GetParameter("p");
                    var mapParam           = mapType.GetParameter("map");
                    var mappedItemSelector = Expression.Lambda(mapType.GetTranslatedParameterOrMember(mapParam), sourceTypeParam, mapParam);

                    var newArgs2 = new Expression[]
                    {
                        translatedSource,
                        selectorTranslation.TranslatedExpression,
                        isQueryable ? Expression.Quote(mappedItemSelector) as Expression : mappedItemSelector
                    };

                    Func <IQueryable <object>, Expression <Func <object, IEnumerable <object> > >, Expression <Func <object, object, object> >, IQueryable <object> > f1 = Queryable.SelectMany;
                    Func <IEnumerable <object>, Func <object, IEnumerable <object> >, Func <object, object, object>, IEnumerable <object> > f2 = Enumerable.SelectMany;
                    var newSelectManyMethod = (isQueryable ? f1.Method : f2.Method).GetGenericMethodDefinition()
                                              .MakeGenericMethod(context.QueryableType.NonPrimitiveEnumerableItemType.TranslatedType,
                                                                 selectorTranslation.QueryableType.NonPrimitiveEnumerableItemType.TranslatedType, mappedItemSelector.Body.Type);

                    context.QueryableType = RuntimeTypes.CreateEnumerable(new SimpleType(mapType.MappedItemType, mappedItemSelector.Body.Type));
                    return(Expression.Call(mce.Object, newSelectManyMethod, newArgs2));
                }

                var newArgs = new Expression[]
                {
                    translatedSource,
                    selectorTranslation.TranslatedExpression
                };

                //SelectMany<TSource, TResult>
                var translatedMethod = mce.Method.GetGenericMethodDefinition().MakeGenericMethod(
                    context.QueryableType.NonPrimitiveEnumerableItemType.TranslatedType,
                    selectorTranslation.QueryableType.NonPrimitiveEnumerableItemType.TranslatedType);

                //IQueryable<TResult>
                context.QueryableType = RuntimeTypes.CreateEnumerable(selectorTranslation.QueryableType.NonPrimitiveEnumerableItemType);

                return(Expression.Call(mce.Object, translatedMethod, newArgs) as Expression);
            }
示例#9
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)
            });
        }
示例#10
0
文件: Join.cs 项目: jeswin/AgileFx
            public override Expression Translate(MethodCallExpression mce, Expression translatedOuter, IEnumerable <Expression> otherArgs, QueryAnalysisContext context)
            {
                bool isQueryable = DefinedOnQueryable(mce);

                var _otherArgs = otherArgs.ToArray();

                //IEnumerable<TInner>
                var innerTranslation = QueryTranslationVisitor.VisitWithNewVisitor(_otherArgs[0], context, false);

                //Func<TOuter, TKey>
                var outerKeySelectorTranslation = QueryTranslationVisitor.TranslateLambda(_otherArgs[1], new[] { context.QueryableType.NonPrimitiveEnumerableItemType }, context, isQueryable);

                //Func<TInner, TKey>
                var innerKeySelectorTranslation = QueryTranslationVisitor.TranslateLambda(_otherArgs[2], new[] { innerTranslation.QueryableType.NonPrimitiveEnumerableItemType }, context, isQueryable);

                //Func<TOuter, TInner, TResult>
                var resultSelectorTranslation = QueryTranslationVisitor.TranslateLambda(_otherArgs[3], new[] { context.QueryableType.NonPrimitiveEnumerableItemType, innerTranslation.QueryableType.NonPrimitiveEnumerableItemType }, context, isQueryable);

                var newArgs = new Expression[]
                {
                    translatedOuter,
                    innerTranslation.TranslatedExpression,
                    outerKeySelectorTranslation.TranslatedExpression,
                    innerKeySelectorTranslation.TranslatedExpression,
                    resultSelectorTranslation.TranslatedExpression
                };

                //Join<TOuter, TInner, TKey, TResult>
                var translatedMethod = mce.Method.GetGenericMethodDefinition().MakeGenericMethod(
                    context.QueryableType.NonPrimitiveEnumerableItemType.TranslatedType,
                    innerTranslation.QueryableType.NonPrimitiveEnumerableItemType.TranslatedType,
                    outerKeySelectorTranslation.QueryableType.TranslatedType,
                    resultSelectorTranslation.QueryableType.TranslatedType);

                context.QueryableType = RuntimeTypes.CreateEnumerable(resultSelectorTranslation.QueryableType);

                return(Expression.Call(mce.Object, translatedMethod, newArgs));
            }
示例#11
0
 public bool Equals(MapRequest other) =>
 RequestedTypes.Equals(other.RequestedTypes) && RuntimeTypes.Equals(other.RuntimeTypes) && Equals(MemberMap, other.MemberMap);
示例#12
0
 public bool Equals(MapRequest other) => RequestedTypes.Equals(other.RequestedTypes) && RuntimeTypes.Equals(other.RuntimeTypes);
示例#13
0
 public bool Equals(MapRequest other) =>
 RequestedTypes.Equals(other.RequestedTypes) && RuntimeTypes.Equals(other.RuntimeTypes) && Equals(PropertyMap, other.PropertyMap);