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));
        }
Ejemplo n.º 2
0
        private DbFilterExpression BuildFilterExpressionWithDynamicFilters(string entityName, IEnumerable <DynamicFilterDefinition> filterList, DbExpressionBinding binding, DbExpression predicate)
        {
            if (!filterList.Any())
            {
                return(null);
            }

            var edmType = binding.VariableType.EdmType as EntityType;

            if (edmType == null)
            {
                return(null);
            }

            List <DbExpression> conditionList = new List <DbExpression>();

            HashSet <string> processedFilterNames = new HashSet <string>();

            foreach (var filter in filterList)
            {
                if (processedFilterNames.Contains(filter.FilterName))
                {
                    continue;       //  Already processed this filter - attribute was probably inherited in a base class
                }
                processedFilterNames.Add(filter.FilterName);

                DbExpression dbExpression;
                if (!string.IsNullOrEmpty(filter.ColumnName))
                {
                    //  Single column equality filter
                    //  Need to map through the EdmType properties to find the actual database/cspace name for the entity property.
                    //  It may be different from the entity property!
                    var edmProp = edmType.Properties.Where(p => p.MetadataProperties.Any(m => m.Name == "PreferredName" && m.Value.Equals(filter.ColumnName))).FirstOrDefault();
                    if (edmProp == null)
                    {
                        continue;       //  ???
                    }
                    //  database column name is now in edmProp.Name.  Use that instead of filter.ColumnName

                    var columnProperty = DbExpressionBuilder.Property(DbExpressionBuilder.Variable(binding.VariableType, binding.VariableName), edmProp.Name);
                    var param          = columnProperty.Property.TypeUsage.Parameter(filter.CreateDynamicFilterName(filter.ColumnName));

                    dbExpression = DbExpressionBuilder.Equal(columnProperty, param);
                }
                else if (filter.Predicate != null)
                {
                    //  Lambda expression filter
                    dbExpression = LambdaToDbExpressionVisitor.Convert(filter, binding, _ObjectContext);
                }
                else
                {
                    throw new System.ArgumentException(string.Format("Filter {0} does not contain a ColumnName or a Predicate!", filter.FilterName));
                }

                //  Create an expression to check to see if the filter has been disabled and include that check with the rest of the filter expression.
                //  When this parameter is null, the filter is enabled.  It will be set to true (in DynamicFilterExtensions.GetFilterParameterValue) if
                //  the filter has been disabled.
                var boolPrimitiveType = LambdaToDbExpressionVisitor.TypeUsageForPrimitiveType(typeof(bool?), _ObjectContext);
                var isDisabledParam   = boolPrimitiveType.Parameter(filter.CreateFilterDisabledParameterName());

                conditionList.Add(DbExpressionBuilder.Or(dbExpression, DbExpressionBuilder.Not(DbExpressionBuilder.IsNull(isDisabledParam))));
            }

            int          numConditions = conditionList.Count;
            DbExpression newPredicate;

            switch (numConditions)
            {
            case 0:
                return(null);

            case 1:
                newPredicate = conditionList.First();
                break;

            default:
                //  Have multiple conditions.  Need to append them together using 'and' conditions.
                newPredicate = conditionList.First();

                for (int i = 1; i < numConditions; i++)
                {
                    newPredicate = newPredicate.And(conditionList[i]);
                }
                break;
            }

            //  'and' the existing Predicate if there is one
            if (predicate != null)
            {
                newPredicate = newPredicate.And(predicate);
            }

            return(DbExpressionBuilder.Filter(binding, newPredicate));
        }