Ejemplo n.º 1
0
    public static Expression <Predicate <T> > Rewrite <T>(Expression <Predicate <T> > exp, string newParamName)
    {
        var param         = Expression.Parameter(exp.Parameters[0].Type, newParamName);
        var newExpression = new PredicateRewriterVisitor(param).Visit(exp);

        return((Expression <Predicate <T> >)newExpression);
    }
Ejemplo n.º 2
0
        public static Expression <Func <TEntity, bool> > Rewrite <TEntity>(Expression <Func <TEntity, bool> > exp, string newParamName)
        {
            ParameterExpression param         = Expression.Parameter(exp.Parameters[0].Type, newParamName);
            Expression          newExpression = new PredicateRewriterVisitor(param).Visit(exp);

            return((Expression <Func <TEntity, bool> >)newExpression);
        }
 public static Expression<Func<T, U>> Rewrite<T,U>(Expression<Func<T, U>> exp, //string newParamName
     ParameterExpression param)
 {
     //var param = Expression.Parameter(exp.Parameters[0].Type, newParamName);
     var newExpression = new PredicateRewriterVisitor(param).Visit(exp);
     return (Expression<Func<T, U>>)newExpression;
 }
Ejemplo n.º 4
0
        public static Expression Rewrite(Expression exp, System.Linq.Expressions.MemberExpression newParameterExpression)
        {
            var param = newParameterExpression;
            var newExpression = new PredicateRewriterVisitor(param).Visit(exp);

            return newExpression;
        }
Ejemplo n.º 5
0
        public static Expression <Func <T1, T2, object> > Rewrite <T1, T2>(Expression <Func <T1, T2, object> > exp, string newParamName)
        {
            var param           = Expression.Parameter(exp.Parameters[1].Type, newParamName);
            var unchangedParams = exp.Parameters.Take(1).ToList();
            var newExpression   = new PredicateRewriterVisitor(param, unchangedParams).Visit(exp);

            return((Expression <Func <T1, T2, object> >)newExpression);
        }
        /// <summary>
        /// <para>
        /// Selecting and including related entities, instead of using the "Include"-Method from EF.
        /// With the "Include"-Method it is not possible to specify conditions what entities to include.
        /// With this method you can specify exactly what entities to load, and how they will be filtered
        /// or ordered.
        /// </para>
        /// <para>
        /// Attention! This selection will use AsEnumerable(). This means, that the database will be
        /// queried at this point of the chain!
        /// </para>
        /// </summary>
        /// <typeparam name="T">Type of Source IQueryable</typeparam>
        /// <param name="source">Source IQueryable</param>
        /// <param name="includeExpessions">Lamda Expressions, defining what entities to include</param>
        /// <returns></returns>
        public static IEnumerable<T> SelectIncluding<T>(this IQueryable<T> source, IEnumerable<Expression<Func<T,object>>> includeExpessions)
        {
            if (source == null) throw new ArgumentNullException("Source Object is NULL");


            //Here we do something similar to this:

            //First, select into a anonymous type with all the related entity-collections you need.
            //The relation can be defined by every query you want.

            //var query = _dbSet
            //    .Select(mainEntity => new
            //    {
            //
            //        //The main object. We need this field to unwrap later.
            //        mainEntity,
            //
            //        //Example how to retrieve only the newest history entry
            //        newestHistoryEntry = mainEntity.HistoryEntries.OrderByDescending(x => x.Timestamp).Take(1),
            //
            //        //Example how to order related entities
            //        itemSpecMSRPrices = mainEntity.OtherEntities.OrderBy(y => y.Something).ThenBy(y => y.SomeOtherThing),
            //
            //        //Example how to retrieve entities one level deeper
            //        secondLevel = mainEntity.CollectionWithRelations.Select(x => x.EntityCollectionOnSecondLevel),
            //
            //        //Of course you can order or subquery the deeper level
            //        //Here you should use SelectMany, to flatten the query
            //        secondLevelOrdered = mainEntity.CollectionWithRelations.SelectMany(x => x.EntityCollectionOnSecondLevel.OrderBy(y => y.Something).ThenBy(y => y.SomeOtherThing)),
            //
            //    });

            //Now we fire up the query (AsEnumerable) and then unwrap the SupplierItem out 
            //of the anonymous type (Select). 
            
            //return query.AsEnumerable().Select(mainEntity => mainEntity.mainEntity);

            //Because the ObjectContext have collected all the related entities, it have also linked each other correctly over 
            //navigation-properties and reference-properties. Please read this Tip, too:
            //http://blogs.msdn.com/b/alexj/archive/2009/10/13/tip-37-how-to-do-a-conditional-include.aspx
            
            //We build here firstly the Expression needed by the Select-Method dynamicly.
            //Beyond this we build even the class dynamicly. The class includes only
            //the Properties we want to project. The difference is, that the class is
            //not an anonymous type. Its a "Type built in Runtime" using Reflection.Emit.

            //Remark to the fields within the dynamic generated class:

            //All of them will be declared with the type really needed. So even the dynamicly
            //generated class will be "strong-type-safe".

            //Remark to the paramter "includeExpressions":

            //The method expect a collection of LambdaExpression-Objects. In fact we do not need
            //the LamdaExpression, but only the body of them. The LambdaExpression is only a
            //pleasant way to enable the user to define expression in a strong-type way.

            //Prepare ParameterExpression refering to the source object
            var sourceItem = Expression.Parameter(source.ElementType, "t");

            //Prepare helper class to replace the user-parameter of the LambdExpression with ours
            var paramRewriter = new PredicateRewriterVisitor(sourceItem);

            //Loop all expression and:
            //  1.) Determine returned type.
            //  2.) Get Body and replace the Parameter used by the user with ours
            //  2.) Give all of them a name and save them in a Dictionary
            Dictionary<string, Tuple<Expression, Type>> dynamicFields = new Dictionary<string, Tuple<Expression, Type>>();
            int dynamicFieldsCounter = 0;
            foreach (Expression<Func<T, object>> includeExpession in includeExpessions)
            {
                //Detect Type
                Type typeDetected;
                if ((includeExpession.Body.NodeType == ExpressionType.Convert) ||
                    (includeExpession.Body.NodeType == ExpressionType.ConvertChecked))
                {
                    var unary = includeExpession.Body as UnaryExpression;
                    if (unary != null)
                        typeDetected = unary.Operand.Type;
                }
                typeDetected = includeExpession.Body.Type;
                //Save into List
                dynamicFields.Add("f" + dynamicFieldsCounter, new Tuple<Expression, Type>(
                    paramRewriter.ReplaceParameter(includeExpession.Body,includeExpession.Parameters[0]),
                    typeDetected
                    ));
                //Count
                dynamicFieldsCounter++;
            }

            //Add a field in which the source object will be saved
            dynamicFields.Add("sourceObject", new Tuple<Expression, Type>(
                sourceItem,
                source.ElementType
                ));

            //Build dynamic a Class that includes the Fields (no inheritance, no interfaces)
            var dynamicType = DynamicTypeBuilder.GetDynamicType(dynamicFields.ToDictionary(x => x.Key, x => x.Value.Item2), typeof(object), Type.EmptyTypes);

            //Create the Binding Expressions
            var bindings = dynamicType.GetFields().Select(p => Expression.Bind(p, dynamicFields[p.Name].Item1)).OfType<MemberBinding>().ToList();

            //Create the Projection
            var selector = Expression.Lambda<Func<T, dynamic>>(Expression.MemberInit(Expression.New(dynamicType.GetConstructor(Type.EmptyTypes)), bindings), sourceItem);

            return source.Select(selector).AsEnumerable().Select(x => (T)x.sourceObject);
        }