コード例 #1
0
        private DbFilterExpression BuildFilterExpressionWithDynamicFilters(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
                    var edmProp = edmType.Properties.FirstOrDefault(p => p.Name == filter.ColumnName);
                    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, DataSpace.CSpace));

                    dbExpression = DbExpressionBuilder.Equal(columnProperty, param);

                    //  When using SSpace, need some special handling for an Oracle Boolean property.
                    //  Not necessary when using CSpace since the translation into the Oracle types has not happened yet.
                }
                else if (filter.Predicate != null)
                {
                    //  Lambda expression filter
                    dbExpression = LambdaToDbExpressionVisitor.Convert(filter, binding, _DbContext, DataSpace.CSpace);
                }
                else
                {
                    throw new System.ArgumentException(string.Format("Filter {0} does not contain a ColumnName or a Predicate!", filter.FilterName));
                }

                if (DynamicFilterExtensions.AreFilterDisabledConditionsAllowed(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, DataSpace.CSpace);
                    var isDisabledParam   = boolPrimitiveType.Parameter(filter.CreateFilterDisabledParameterName(DataSpace.CSpace));

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

            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));
        }
        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));

                    if ((columnProperty.ResultType.EdmType.FullName == "Edm.Boolean") &&
                        param.ResultType.EdmType.FullName.StartsWith("Oracle", StringComparison.CurrentCultureIgnoreCase) && (param.ResultType.EdmType.Name == "number"))       //  Don't trust Oracle's type name to stay the same...
                    {
                        //  Special handling needed for columnProperty boolean.  For some reason, the Oracle EF driver does not correctly
                        //  set the ResultType to a number(1) in columnProperty like it does in columnProperty.Property.TypeUsage.  That
                        //  results in us trying to do a comparison of a Boolean to a number(1) which causes DbExpressionBuilder.Equal
                        //  to throw an exception.  To get this to process correctly, we need to do a cast on the columnProperty to
                        //  "number(1)" so that it matches the param.ResultType.  And that results in the sql sent to Oracle converting
                        //  the column to the type that it already is...
                        dbExpression = DbExpressionBuilder.Equal(DbExpressionBuilder.CastTo(columnProperty, param.ResultType), param);
                    }
                    else
                    {
                        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));
                }

                if (DynamicFilterExtensions.AreFilterDisabledConditionsAllowed(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))));
                }
                else
                {
                    conditionList.Add(dbExpression);
                }
            }

            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));
        }