private DbExpressionBinding VisitExpressionBindingEnterScope(DbExpressionBinding binding) { var result = VisitExpressionBinding(binding); OnEnterScope(new[] { result.Variable }); return(result); }
internal DbDeleteCommandTree(MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, DbExpression predicate) : base(metadata, dataSpace, target) { Contract.Requires(predicate != null); _predicate = predicate; }
internal DbModificationCommandTree(MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target) : base(metadata, dataSpace) { DebugCheck.NotNull(target); _target = target; }
internal DbModificationCommandTree(MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target) : base(metadata, dataSpace) { Contract.Requires(target != null); _target = target; }
/// <summary> /// Initializes a new instance of the <see cref="DbDeleteCommandTree"/> class. /// </summary> /// <param name="metadata">The model this command will operate on.</param> /// <param name="dataSpace">The data space.</param> /// <param name="target">The target table for the data manipulation language (DML) operation.</param> /// <param name="predicate">A predicate used to determine which members of the target collection should be deleted.</param> public DbDeleteCommandTree(MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, DbExpression predicate) : base(metadata, dataSpace, target) { DebugCheck.NotNull(predicate); _predicate = predicate; }
/// <summary> /// Initializes a new instance of the <see cref="DbDeleteCommandTree"/> class. /// </summary> /// <param name="metadata">The model this command will operate on.</param> /// <param name="dataSpace">The data space.</param> /// <param name="target">The target table for the data manipulation language (DML) operation.</param> /// <param name="predicate">A predicate used to determine which members of the target collection should be deleted.</param> public DbDeleteCommandTree(MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, DbExpression predicate) : base(metadata, dataSpace, target) { DebugCheck.NotNull(predicate); _predicate = predicate; }
internal DbModificationCommandTree(MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target) : base(metadata, dataSpace) { DebugCheck.NotNull(target); _target = target; }
internal DbModificationCommandTree( MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target) : base(metadata, dataSpace, true) { this._target = target; }
internal DbFilterExpression( TypeUsage resultType, DbExpressionBinding input, DbExpression predicate) : base(DbExpressionKind.Filter, resultType, true) { this._input = input; this._predicate = predicate; }
internal DbProjectExpression( TypeUsage resultType, DbExpressionBinding input, DbExpression projection) : base(DbExpressionKind.Project, resultType, true) { this._input = input; this._projection = projection; }
/// <summary> /// Initializes a new instance of the <see cref="T:System.Data.Entity.Core.Common.CommandTrees.DbDeleteCommandTree" /> class. /// </summary> /// <param name="metadata">The model this command will operate on.</param> /// <param name="dataSpace">The data space.</param> /// <param name="target">The target table for the data manipulation language (DML) operation.</param> /// <param name="predicate">A predicate used to determine which members of the target collection should be deleted.</param> public DbDeleteCommandTree( MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, DbExpression predicate) : base(metadata, dataSpace, target) { this._predicate = predicate; }
internal DbSortExpression( TypeUsage resultType, DbExpressionBinding input, ReadOnlyCollection <DbSortClause> sortOrder) : base(DbExpressionKind.Sort, resultType, true) { this._input = input; this._keys = sortOrder; }
internal DbProjectExpression(TypeUsage resultType, DbExpressionBinding input, DbExpression projection) : base(DbExpressionKind.Project, resultType) { DebugCheck.NotNull(input); DebugCheck.NotNull(projection); _input = input; _projection = projection; }
internal DbApplyExpression( DbExpressionKind applyKind, TypeUsage resultRowCollectionTypeUsage, DbExpressionBinding input, DbExpressionBinding apply) : base(applyKind, resultRowCollectionTypeUsage, true) { this._input = input; this._apply = apply; }
internal DbSortExpression(TypeUsage resultType, DbExpressionBinding input, ReadOnlyCollection <DbSortClause> sortOrder) : base(DbExpressionKind.Sort, resultType) { DebugCheck.NotNull(input); DebugCheck.NotNull(sortOrder); Debug.Assert(TypeSemantics.IsCollectionType(resultType), "DbSkipExpression requires a collection result type"); _input = input; _keys = sortOrder; }
internal DbQuantifierExpression( DbExpressionKind kind, TypeUsage booleanResultType, DbExpressionBinding input, DbExpression predicate) : base(kind, booleanResultType, true) { this._input = input; this._predicate = predicate; }
/// <summary> /// Initializes a new instance of the <see cref="T:System.Data.Entity.Core.Common.CommandTrees.DbInsertCommandTree" /> class. /// </summary> /// <param name="metadata">The model this command will operate on.</param> /// <param name="dataSpace">The data space.</param> /// <param name="target">The target table for the data manipulation language (DML) operation.</param> /// <param name="setClauses">The list of insert set clauses that define the insert operation. .</param> /// <param name="returning">A <see cref="T:System.Data.Entity.Core.Common.CommandTrees.DbExpression" /> that specifies a projection of results to be returned, based on the modified rows.</param> public DbInsertCommandTree( MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, ReadOnlyCollection <DbModificationClause> setClauses, DbExpression returning) : base(metadata, dataSpace, target) { this._setClauses = setClauses; this._returning = returning; }
internal DbSkipExpression( TypeUsage resultType, DbExpressionBinding input, ReadOnlyCollection <DbSortClause> sortOrder, DbExpression count) : base(DbExpressionKind.Skip, resultType, true) { this._input = input; this._keys = sortOrder; this._count = count; }
/// <summary> /// Initializes a new instance of the <see cref="DbInsertCommandTree"/> class. /// </summary> /// <param name="metadata">The model this command will operate on.</param> /// <param name="dataSpace">The data space.</param> /// <param name="target">The target table for the data manipulation language (DML) operation.</param> /// <param name="setClauses">The list of insert set clauses that define the insert operation. .</param> /// <param name="returning">A <see cref="DbExpression"/> that specifies a projection of results to be returned, based on the modified rows.</param> public DbInsertCommandTree( MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, ReadOnlyModificationClauses setClauses, DbExpression returning) : base(metadata, dataSpace, target) { DebugCheck.NotNull(setClauses); // returning may be null _setClauses = setClauses; _returning = returning; }
/// <summary> /// Initializes a new instance of the <see cref="DbInsertCommandTree"/> class. /// </summary> /// <param name="metadata">The model this command will operate on.</param> /// <param name="dataSpace">The data space.</param> /// <param name="target">The target table for the data manipulation language (DML) operation.</param> /// <param name="setClauses">The list of insert set clauses that define the insert operation. .</param> /// <param name="returning">A <see cref="DbExpression"/> that specifies a projection of results to be returned, based on the modified rows.</param> public DbInsertCommandTree( MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, ReadOnlyModificationClauses setClauses, DbExpression returning) : base(metadata, dataSpace, target) { DebugCheck.NotNull(setClauses); // returning may be null _setClauses = setClauses; _returning = returning; }
internal DbInsertCommandTree( MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, ReadOnlyModificationClauses setClauses, DbExpression returning) : base(metadata, dataSpace, target) { Contract.Requires(setClauses != null); // returning may be null _setClauses = setClauses; _returning = returning; }
internal DbFilterExpression(TypeUsage resultType, DbExpressionBinding input, DbExpression predicate) : base(DbExpressionKind.Filter, resultType) { DebugCheck.NotNull(input); DebugCheck.NotNull(predicate); Debug.Assert( TypeSemantics.IsPrimitiveType(predicate.ResultType, PrimitiveTypeKind.Boolean), "DbFilterExpression predicate must have a Boolean result type"); _input = input; _predicate = predicate; }
internal DbJoinExpression( DbExpressionKind joinKind, TypeUsage collectionOfRowResultType, DbExpressionBinding left, DbExpressionBinding right, DbExpression condition) : base(joinKind, collectionOfRowResultType, true) { this._left = left; this._right = right; this._condition = condition; }
internal DbApplyExpression( DbExpressionKind applyKind, TypeUsage resultRowCollectionTypeUsage, DbExpressionBinding input, DbExpressionBinding apply) : base(applyKind, resultRowCollectionTypeUsage) { DebugCheck.NotNull(input); DebugCheck.NotNull(apply); Debug.Assert( DbExpressionKind.CrossApply == applyKind || DbExpressionKind.OuterApply == applyKind, "Invalid DbExpressionKind for DbApplyExpression"); _input = input; _apply = apply; }
internal DbUpdateCommandTree( MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, DbExpression predicate, ReadOnlyModificationClauses setClauses, DbExpression returning) : base(metadata, dataSpace, target) { DebugCheck.NotNull(predicate); DebugCheck.NotNull(setClauses); // returning is allowed to be null _predicate = predicate; _setClauses = setClauses; _returning = returning; }
/// <summary> /// Initializes a new instance of the <see cref="DbUpdateCommandTree"/> class. /// </summary> /// <param name="metadata">The model this command will operate on.</param> /// <param name="dataSpace">The data space.</param> /// <param name="target">The target table for the data manipulation language (DML) operation.</param> /// <param name="predicate">A predicate used to determine which members of the target collection should be updated.</param> /// <param name="setClauses">The list of update set clauses that define the update operation.</param> /// <param name="returning">A <see cref="DbExpression"/> that specifies a projection of results to be returned, based on the modified rows.</param> public DbUpdateCommandTree( MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, DbExpression predicate, ReadOnlyModificationClauses setClauses, DbExpression returning) : base(metadata, dataSpace, target) { DebugCheck.NotNull(predicate); DebugCheck.NotNull(setClauses); // returning is allowed to be null _predicate = predicate; _setClauses = setClauses; _returning = returning; }
internal DbUpdateCommandTree( MetadataWorkspace metadata, DataSpace dataSpace, DbExpressionBinding target, DbExpression predicate, ReadOnlyModificationClauses setClauses, DbExpression returning) : base(metadata, dataSpace, target) { Contract.Requires(predicate != null); Contract.Requires(setClauses != null); // returning is allowed to be null _predicate = predicate; _setClauses = setClauses; _returning = returning; }
/// <summary> /// Helper method creating the correct filter expression based on the supplied parameters /// </summary> private DbFilterExpression BuildFilterExpression(DbExpressionBinding binding, string column) { var variableReference = DbExpressionBuilder.Variable(binding.VariableType, binding.VariableName); // Create the property based on the variable in order to apply the equality var userProperty = DbExpressionBuilder.Property(variableReference, column); // Create the parameter which is an object representation of a sql parameter. // We have to create a parameter and not perform a direct comparison with Equal function for example // as this logic is cached per query and called only once var userParameter = DbExpressionBuilder.Parameter(userProperty.Property.TypeUsage, UserAwareAttribute.UserIdFilterParameterName); // Apply the equality between property and parameter. DbExpression newPredicate = DbExpressionBuilder.Equal(userProperty, userParameter); return DbExpressionBuilder.Filter(binding, newPredicate); }
protected virtual DbExpressionBinding VisitExpressionBinding(DbExpressionBinding binding) { var result = binding; if (binding != null) { var newInput = VisitExpression(binding.Expression); if (!ReferenceEquals(binding.Expression, newInput)) { result = CqtBuilder.BindAs(newInput, binding.VariableName); RebindVariable(binding.Variable, result.Variable); } } return(result); }
internal DbJoinExpression( DbExpressionKind joinKind, TypeUsage collectionOfRowResultType, DbExpressionBinding left, DbExpressionBinding right, DbExpression condition) : base(joinKind, collectionOfRowResultType) { DebugCheck.NotNull(left); DebugCheck.NotNull(right); DebugCheck.NotNull(condition); Debug.Assert( DbExpressionKind.InnerJoin == joinKind || DbExpressionKind.LeftOuterJoin == joinKind || DbExpressionKind.FullOuterJoin == joinKind, "Invalid DbExpressionKind specified for DbJoinExpression"); _left = left; _right = right; _condition = condition; }
/// <summary> /// Helper method creating the correct filter expression based on the supplied parameters /// </summary> private DbFilterExpression BuildFilterExpression(DbExpressionBinding binding, DbExpression predicate, string column) { _injectedDynamicFilter = true; var variableReference = DbExpressionBuilder.Variable(binding.VariableType, binding.VariableName); // Create the property based on the variable in order to apply the equality var tenantProperty = DbExpressionBuilder.Property(variableReference, column); // Create the parameter which is an object representation of a sql parameter. // We have to create a parameter and not perform a direct comparison with Equal function for example // as this logic is cached per query and called only once var tenantParameter = DbExpressionBuilder.Parameter(tenantProperty.Property.TypeUsage, TenantAwareAttribute.TenantIdFilterParameterName); // Apply the equality between property and parameter. DbExpression newPredicate = DbExpressionBuilder.Equal(tenantProperty, tenantParameter); // If an existing predicate exists (normally when called from DbFilterExpression) execute a logical AND to get the result if (predicate != null) newPredicate = newPredicate.And(predicate); return DbExpressionBuilder.Filter(binding, newPredicate); }
// <summary> // Marks current scope region as performing group/folding operation. // </summary> internal void EnterGroupOperation(DbExpressionBinding groupAggregateBinding) { Debug.Assert(!IsAggregating, "Scope region group operation is not reentrant."); _groupAggregateBinding = groupAggregateBinding; }
// Utility translator method for lambda expressions. Given a lambda expression and its translated // inputs, translates the lambda expression, assuming the input is a collection private DbExpression TranslateLambda( LambdaExpression lambda, DbExpression input, string bindingName, out DbExpressionBinding binding) { input = NormalizeSetSource(input); // create binding context for this lambda expression binding = input.BindAs(bindingName); return TranslateLambda(lambda, binding.Variable); }
internal DbExpression Filter(DbExpressionBinding input, DbExpression predicate) { var lifter = GetLifter(input.Expression); return lifter.Filter(input.Filter(predicate)); }
internal DbExpression Project(DbExpressionBinding input, DbExpression projection) { var lifter = GetLifter(input.Expression); return lifter.Project(input.Project(projection)); }
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)); // 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); }
internal DbExpression Skip(DbExpressionBinding input, DbExpression skipCount) { var lifter = GetLifter(input.Expression); return lifter.Skip(skipCount); }
public BindingNormalizer(DbExpressionBinding binding) { _binding = binding; }
/// <summary> /// Convenience method to visit the specified <see cref="DbExpressionBinding"/>. /// </summary> /// <param name="binding">The DbExpressionBinding to visit.</param> /// <exception cref="ArgumentNullException"><paramref name="binding"/> is null</exception> protected virtual void VisitExpressionBindingPre(DbExpressionBinding binding) { ADP1.CheckArgumentNull(binding, "binding"); VisitExpression(binding.Expression); }
/// <summary> /// Convenience method to visit the specified <see cref="DbExpressionBinding" />. /// </summary> /// <param name="binding"> The DbExpressionBinding to visit. </param> /// <exception cref="ArgumentNullException"> /// <paramref name="binding" /> /// is null /// </exception> protected virtual void VisitExpressionBindingPre(DbExpressionBinding binding) { Check.NotNull(binding, "binding"); VisitExpression(binding.Expression); }
private SqlFragment HandleJoinExpression(DbExpressionBinding left, DbExpressionBinding right, DbExpressionKind joinType, DbExpression joinCondition) { JoinFragment join = new JoinFragment(); join.JoinType = Metadata.GetOperator(joinType); join.Left = VisitInputExpression(left.Expression, left.VariableName, left.VariableType); join.Left = WrapJoinInputIfNecessary(join.Left, false); join.Right = VisitInputExpression(right.Expression, right.VariableName, right.VariableType); join.Right = WrapJoinInputIfNecessary(join.Right, true); if (join.Right is SelectStatement) { SelectStatement select = join.Right as SelectStatement; if (select.IsWrapped) select.Name = right.VariableName; } // now handle the ON case if (joinCondition != null) join.Condition = joinCondition.Accept(this); return join; }
private DbExpression Skip(DbExpressionBinding input, DbExpression skipCount) { var retExpr = _orderByLifter.Skip(input, skipCount); ApplySpanMapping(input.Expression, retExpr); return retExpr; }
private DbSortExpression Sort(DbExpressionBinding input, IList<DbSortClause> keys) { var retExpr = input.Sort(keys); ApplySpanMapping(input.Expression, retExpr); return retExpr; }
private DbExpression Project(DbExpressionBinding input, DbExpression projection) { var retExpr = _orderByLifter.Project(input, projection); // For identity projection only, the Span is preserved if (projection.ExpressionKind == DbExpressionKind.VariableReference && ((DbVariableReferenceExpression)projection).VariableName.Equals(input.VariableName, StringComparison.Ordinal)) { ApplySpanMapping(input.Expression, retExpr); } return retExpr; }
/// <summary> /// Convenience method to visit the specified <see cref="T:System.Data.Entity.Core.Common.CommandTrees.DbExpressionBinding" />. /// </summary> /// <param name="binding"> The DbExpressionBinding to visit. </param> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="binding" /> /// is null /// </exception> protected virtual void VisitExpressionBindingPre(DbExpressionBinding binding) { Check.NotNull <DbExpressionBinding>(binding, nameof(binding)); this.VisitExpression(binding.Expression); }
/// <summary> /// Convenience method for post-processing after a DbExpressionBinding has been visited. /// </summary> /// <param name="binding"> The previously visited DbExpressionBinding. </param> protected virtual void VisitExpressionBindingPost(DbExpressionBinding binding) { }
/// <summary> /// Convenience method for post-processing after a DbExpressionBinding has been visited. /// </summary> /// <param name="binding"> The previously visited DbExpressionBinding. </param> protected virtual void VisitExpressionBindingPost(DbExpressionBinding binding) { }
// Effects: given a "clause" in the form of a property/value pair, produces an equality expression. If the // value is null, creates an IsNull expression // Requires: all arguments are set private DbExpression GenerateEqualityExpression(DbExpressionBinding target, EdmProperty property, PropagatorResult value) { DebugCheck.NotNull(target); DebugCheck.NotNull(property); DebugCheck.NotNull(value); var propertyExpression = GeneratePropertyExpression(target, property); var valueExpression = GenerateValueExpression(property, value); if (valueExpression.ExpressionKind == DbExpressionKind.Null) { return propertyExpression.IsNull(); } return propertyExpression.Equal(valueExpression); }
/// <summary> /// Helper method for <see cref="TransformIntersectOrExcept(DbExpression left, DbExpression right, DbExpressionKind expressionKind, IList<DbPropertyExpression> sortExpressionsOverLeft, string sortExpressionsBindingVariableName)"/> /// Creates a <see cref="DbProjectExpression"/> over the given inputBinding that projects out the given flattenedProperties. /// and updates the flattenedProperties to be over the newly created project. /// </summary> /// <param name="inputBinding"></param> /// <param name="flattenedProperties"></param> /// <returns>An <see cref="DbExpressionBinding"/> over the newly created <see cref="DbProjectExpression"/></returns> private static DbExpressionBinding CapWithProject(DbExpressionBinding inputBinding, IList<DbPropertyExpression> flattenedProperties) { var projectColumns = new List<KeyValuePair<string, DbExpression>>(flattenedProperties.Count); //List of all the columnNames used in the projection. var columnNames = new Dictionary<string, int>(flattenedProperties.Count); foreach (var pe in flattenedProperties) { //There may be conflicting property names, thus we may need to rename. var name = pe.Property.Name; int i; if (columnNames.TryGetValue(name, out i)) { string newName; do { ++i; newName = name + i.ToString(CultureInfo.InvariantCulture); } while (columnNames.ContainsKey(newName)); columnNames[name] = i; name = newName; } // Add this column name to list of known names so that there are no subsequent // collisions columnNames[name] = 0; projectColumns.Add(new KeyValuePair<string, DbExpression>(name, pe)); } //Build the project DbExpression rowExpr = DbExpressionBuilder.NewRow(projectColumns); var projectExpression = inputBinding.Project(rowExpr); //Create the new inputBinding var resultBinding = projectExpression.Bind(); //Create the list of flattenedProperties over the new project flattenedProperties.Clear(); var rowExprType = (RowType)rowExpr.ResultType.EdmType; foreach (var column in projectColumns) { var prop = rowExprType.Properties[column.Key]; flattenedProperties.Add(resultBinding.Variable.Property(prop)); } return resultBinding; }
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); }
/// <summary> /// Convenience method to visit the specified <see cref="DbExpressionBinding" />. /// </summary> /// <param name="binding"> The DbExpressionBinding to visit. </param> /// <exception cref="ArgumentNullException"> /// <paramref name="binding" /> /// is null /// </exception> protected virtual void VisitExpressionBindingPre(DbExpressionBinding binding) { Check.NotNull(binding, "binding"); VisitExpression(binding.Expression); }
private DbExpression Filter(DbExpressionBinding input, DbExpression predicate) { var retExpr = _orderByLifter.Filter(input, predicate); ApplySpanMapping(input.Expression, retExpr); return retExpr; }
protected virtual void VisitExpressionBindingPre(DbExpressionBinding binding) { if (binding == null) throw new ArgumentException("binding"); VisitExpression(binding.Expression); }
// Effects: given a property, produces a property expression // Requires: all arguments are set private static DbExpression GeneratePropertyExpression(DbExpressionBinding target, EdmProperty property) { DebugCheck.NotNull(target); DebugCheck.NotNull(property); return target.Variable.Property(property); }