public static DbExpression Convert(DynamicFilterDefinition filter, DbExpressionBinding binding, ObjectContext objectContext)
        {
            var visitor    = new LambdaToDbExpressionVisitor(filter, binding, objectContext);
            var expression = visitor.Visit(filter.Predicate) as LambdaExpression;

            return(visitor.GetDbExpressionForExpression(expression.Body));
        }
示例#2
0
        public static DbExpression Convert(DynamicFilterDefinition filter, DbExpressionBinding binding, DbContext dbContext, DataSpace dataSpace)
        {
            var visitor    = new LambdaToDbExpressionVisitor(filter, binding, dbContext, dataSpace);
            var expression = visitor.Visit(filter.Predicate) as LambdaExpression;

            var dbExpression = visitor.GetDbExpressionForExpression(expression.Body);

            if (dbExpression is DbPropertyExpression)
            {
                //  Special case to handle a condition that is just a plain "boolFlag" or a nullable generic condition.
                //  For a nullable type, we only get here when the filter has either not specified a value for the nullable
                //  parameter or it has specified "null" - both evaluate the same as far as the method prototypes can tell
                //  since the method signature is "param = null".  This needs to generate a sql "is null" condition.
                //  Otherwise, no param value was specified so we are assuming that we need to generate a "positive"
                //  condition.  i.e. the filter just said "b.prop" which generally means "b.prop == true".
                //  To generate that condition correctly for all types (may not necessarily be a bool), we create a condition
                //  like "!(b.prop == [defaultValue])"

                if (IsNullableType(expression.Body.Type))
                {
                    dbExpression = DbExpressionBuilder.IsNull(dbExpression);
                }
                else
                {
                    var defaultValue = DbExpressionBuilder.Constant(dbExpression.ResultType, Activator.CreateInstance(expression.Body.Type));
                    dbExpression = DbExpressionBuilder.Not(DbExpressionBuilder.Equal(dbExpression, defaultValue));
                }
            }

            return(dbExpression);
        }
        public static DbExpression Convert(DynamicFilterDefinition filter, DbExpressionBinding binding, DbContext dbContext, DataSpace dataSpace)
        {
            var visitor    = new LambdaToDbExpressionVisitor(filter, binding, dbContext, dataSpace);
            var expression = visitor.Visit(filter.Predicate) as LambdaExpression;

            var dbExpression = visitor.GetDbExpressionForExpression(expression.Body);

            if (dbExpression is DbPropertyExpression)
            {
                //  Special case to handle a condition that is just a plan "boolFlag" condition.
                //  In order for the sql to generate correct, we need to turn this into "boolFlag = true"
                //  Figuring out the defaultValue like this should produce the default (0, false, empty) value for the type
                //  we are working with.  So checking then generating a condition of "not (@var = defaultValue)" should produce
                //  the correct condition.
                var defaultValue = DbExpressionBuilder.Constant(dbExpression.ResultType, Activator.CreateInstance(expression.Body.Type));
                dbExpression = DbExpressionBuilder.Not(DbExpressionBuilder.Equal(dbExpression, defaultValue));
            }

            return(dbExpression);
        }
        private Expression MapAnyOrAllExpression(MethodCallExpression node)
        {
            if (_DataSpace != DataSpace.CSpace)
            {
                throw new ApplicationException("Filters on child collections are only supported when using CSpace");
            }

            if ((node.Arguments == null) || (node.Arguments.Count > 2))
            {
                throw new ApplicationException("Any function call has more than 2 arguments");
            }

            //  Visit the first argument so that we can get the DbPropertyExpression which is the source of the method call.
            var sourceExpression     = Visit(node.Arguments[0]);
            var collectionExpression = GetDbExpressionForExpression(sourceExpression);

            //  Visit this DbExpression using the QueryVisitor in case it has it's own filters that need to be applied.
            var queryVisitor = new DynamicFilterQueryVisitorCSpace(_DbContext);

            collectionExpression = collectionExpression.Accept(queryVisitor);

            DbExpression dbExpression;

            if (node.Arguments.Count == 2)
            {
                //  The method call has a predicate that needs to be evaluated.  This must be done against the source
                //  argument - not the current binding.
                var binding = collectionExpression.Bind();

                //  Visit the lambda expression against this binding (which will evaluate all of the
                //  conditions in the expression against this binding and for this filter).
                var lambdaExpression = node.Arguments[1] as LambdaExpression;
                var visitor          = new LambdaToDbExpressionVisitor(_Filter, binding, _DbContext, _DataSpace);
                var subExpression    = visitor.Visit(lambdaExpression) as LambdaExpression;
                var subDbExpression  = visitor.GetDbExpressionForExpression(subExpression.Body);

                //  Create an "Any" or "All" DbExpression from the results
                if (node.Method.Name == "All")
                {
                    dbExpression = DbExpressionBuilder.All(binding, subDbExpression);
                }
                else
                {
                    dbExpression = DbExpressionBuilder.Any(binding, subDbExpression);
                }
            }
            else
            {
                //  This should not even be possible - linq/IEnumerable does not have such a method!
                if (node.Method.Name == "All")
                {
                    throw new ApplicationException("All() with no parameters is not supported");
                }

                //  No predicate so just create an Any DbExpression against the collection expression
                dbExpression = DbExpressionBuilder.Any(collectionExpression);
            }

            MapExpressionToDbExpression(node, dbExpression);
            return(node);
        }