Expression IQueryPolicy.ApplyPolicy(Expression expression, MemberInfo member) { List <LambdaExpression> ops; if (operations.TryGetValue(member, out ops)) { var syntax = Database.Provider.GetService <ISyntaxProvider>(); var result = expression; foreach (var fnOp in ops) { var pop = PartialEvaluator.Eval(fnOp); result = QueryBinder.Bind(Expression.Invoke(pop, result), syntax); } var projection = (ProjectionExpression)result; if (projection.Type != expression.Type) { var fnAgg = QueryUtility.GetAggregator(expression.Type, projection.Type); projection = new ProjectionExpression(projection.Select, projection.Projector, fnAgg); } return(projection); } return(expression); }
/// <summary> /// Apply mapping translations to this expression /// </summary> /// <param name="expression"></param> /// <returns></returns> public virtual Expression Translate(Expression expression) { // convert references to LINQ operators into query specific nodes expression = QueryBinder.Bind(this, expression); // move aggregate computations so they occur in same select as group-by expression = AggregateRewriter.Rewrite(this.Translator.Linguist.Language, expression); // do reduction so duplicate association's are likely to be clumped together expression = UnusedColumnRemover.Remove(expression); expression = RedundantColumnRemover.Remove(expression); expression = RedundantSubqueryRemover.Remove(expression); expression = RedundantJoinRemover.Remove(expression); // convert references to association properties into correlated queries var bound = RelationshipBinder.Bind(this, expression); if (bound != expression) { expression = bound; // clean up after ourselves! (multiple references to same association property) expression = RedundantColumnRemover.Remove(expression); expression = RedundantJoinRemover.Remove(expression); } // rewrite comparision checks between entities and multi-valued constructs expression = ComparisonRewriter.Rewrite(this.Mapping, expression); return(expression); }
private Expression TranslateInternal(Expression expression, TranslateOptions options) { var syntax = TranslateScope.Current.Context.Database.Provider.GetService <ISyntaxProvider>(); var translation = QueryBinder.Bind(expression, syntax); translation = LogicalDeleteFlagRewriter.Rewrite(translation); translation = GlobalQueryPolicyRewriter.Rewrite(translation); translation = AggregateRewriter.Rewrite(translation); translation = UnusedColumnRemover.Remove(translation); translation = RedundantColumnRemover.Remove(translation); translation = RedundantSubqueryRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); var bound = RelationshipBinder.Bind(translation); if (bound != translation) { translation = bound; translation = RedundantColumnRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); } translation = ComparisonRewriter.Rewrite(translation); var rewritten = RelationshipIncluder.Include(TranslateScope.Current.Context, translation); if (rewritten != translation) { translation = rewritten; translation = UnusedColumnRemover.Remove(translation); translation = RedundantColumnRemover.Remove(translation); translation = RedundantSubqueryRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); } rewritten = SingletonProjectionRewriter.Rewrite(translation); if (rewritten != translation) { translation = rewritten; translation = UnusedColumnRemover.Remove(translation); translation = RedundantColumnRemover.Remove(translation); translation = RedundantSubqueryRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); } rewritten = ClientJoinedProjectionRewriter.Rewrite(translation); if (rewritten != translation) { translation = rewritten; translation = UnusedColumnRemover.Remove(translation); translation = RedundantColumnRemover.Remove(translation); translation = RedundantSubqueryRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); } translation = BuildExpression(translation); return(translation); }
private ProjectionExpression Translate(Expression expression) { expression = Evaluator.PartialEval(expression, CanBeEvaluatedLocally); expression = QueryBinder.Bind(this, expression); expression = SubstringExpressionRewriter.Rewrite(expression); expression = SubstringEmptyClauseRemover.Rewrite(expression); expression = BinaryExpressionRewriter.Rewrite(expression); expression = AttributeComparisonReorderingRewriter.Rewrite(expression); expression = NullComparisonRewriter.Rewrite(expression); expression = AndOrExpressionCollector.Rewrite(expression); expression = RedundantExpressionRemover.Rewrite(expression); return((ProjectionExpression)expression); }
internal static Expression Bind(DataAccessModel dataAccessModel, SqlDataTypeProvider sqlDataTypeProvider, Expression expression) { var placeholderCount = -1; expression = Evaluator.PartialEval(expression, ref placeholderCount); expression = QueryBinder.Bind(dataAccessModel, expression); expression = SqlEnumTypeNormalizer.Normalize(expression, sqlDataTypeProvider.GetTypeForEnums()); expression = Evaluator.PartialEval(expression, ref placeholderCount); expression = SqlNullComparisonCoalescer.Coalesce(expression); expression = SqlTupleOrAnonymousTypeComparisonExpander.Expand(expression); expression = SqlObjectOperandComparisonExpander.Expand(expression); expression = SqlRedundantFunctionCallRemover.Remove(expression); return(expression); }
internal Expression Translate(Expression expression) { if (expression is ProjectionExpression projection) { return(projection); } expression = Evaluator.PartialEval(expression, CanBeEvaluatedLocally); expression = QueryBinder.Bind(this, expression); expression = ConstantEscaper.EscapeConstants(expression); expression = OrderByRewriter.Rewrite(expression); expression = RedundantSubqueryRemover.Remove(expression); expression = UnusedColumnRemover.Remove(expression); expression = AggregateSimplifier.Simplify(expression); return(expression); }
public override string GetQueryText(Expression expression) { SqlProjectionExpression projectionExpression; if (this.RelatedDataAccessObjectContext == null) { projectionExpression = (SqlProjectionExpression)(QueryBinder.Bind(this.DataAccessModel, expression, null, null)); } else { projectionExpression = (SqlProjectionExpression)(QueryBinder.Bind(this.DataAccessModel, expression, this.RelatedDataAccessObjectContext.ElementType, this.RelatedDataAccessObjectContext.ExtraCondition)); } var result = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(projectionExpression); return(result.CommandText); }
public virtual Expression Translate(Expression expression) { expression = QueryBinder.Bind(this, expression); expression = AggregateRewriter.Rewrite(this.Translator.Linguist.Language, expression); expression = UnusedColumnRemover.Remove(expression); expression = RedundantColumnRemover.Remove(expression); expression = RedundantSubqueryRemover.Remove(expression); expression = RedundantJoinRemover.Remove(expression); Expression expression2 = RelationshipBinder.Bind(this, expression); if (expression2 != expression) { expression = expression2; expression = RedundantColumnRemover.Remove(expression); expression = RedundantJoinRemover.Remove(expression); } expression = ComparisonRewriter.Rewrite(this.Mapping, expression); return(expression); }
public static void DeleteWhere <T>(this DataAccessObjectsQueryable <T> queryable, Expression <Func <T, bool> > condition) where T : DataAccessObject { queryable.DataAccessModel.Flush(); var transactionContext = queryable.DataAccessModel.AmbientTransactionManager.GetCurrentContext(true); using (var acquisition = transactionContext.AcquirePersistenceTransactionContext(queryable.DataAccessModel.GetCurrentSqlDatabaseContext())) { var expression = (Expression)Expression.Call(null, MethodCache <T> .DeleteMethod, Expression.Constant(queryable, typeof(DataAccessObjectsQueryable <T>)), condition); expression = Evaluator.PartialEval(expression); expression = QueryBinder.Bind(queryable.DataAccessModel, expression, queryable.ElementType, queryable.ExtraCondition); expression = ObjectOperandComparisonExpander.Expand(expression); expression = SqlQueryProvider.Optimize(expression, transactionContext.SqlDatabaseContext.SqlDataTypeProvider.GetTypeForEnums()); acquisition.SqlDatabaseCommandsContext.Delete((SqlDeleteExpression)expression); } }
internal Expression ApplyPolicy(Expression expression, MemberInfo member) { List <LambdaExpression> ops; if (Operations.TryGetValue(member, out ops)) { var result = expression; foreach (var fnOp in ops) { var pop = PartialEvaluator.Eval(fnOp, ExpressionHelper.CanBeEvaluatedLocally); result = QueryBinder.Bind(ExpressionBuilder, this, Expression.Invoke(pop, result)); } var projection = (ProjectionExpression)result; if (projection.Type != expression.Type) { var fnAgg = Aggregator.GetAggregator(expression.Type, projection.Type); projection = new ProjectionExpression(projection.Select, projection.Projector, fnAgg); } return(projection); } return(expression); }
/// <summary> /// Apply mapping translations to this expression /// </summary> /// <param name="expression"></param> /// <returns></returns> public virtual Expression Translate(Expression expression) { // convert references to LINQ operators into query specific nodes expression = QueryBinder.Bind(this, expression); // move aggregate computations so they occur in same select as group-by expression = AggregateRewriter.Rewrite(expression); // do reduction so duplicate association's are likely to be clumped together expression = UnusedColumnRemover.Remove(expression); expression = RedundantColumnRemover.Remove(expression); expression = RedundantSubqueryRemover.Remove(expression); expression = RedundantJoinRemover.Remove(expression); // convert references to association properties into correlated queries expression = RelationshipBinder.Bind(this, expression); // clean up after ourselves! (multiple references to same association property) expression = RedundantColumnRemover.Remove(expression); expression = RedundantJoinRemover.Remove(expression); return(expression); }
public override void Delete(Type type, IEnumerable <DataAccessObject> dataAccessObjects) { var typeDescriptor = this.DataAccessModel.GetTypeDescriptor(type); var parameter = Expression.Parameter(typeDescriptor.Type, "value"); Expression body = null; foreach (var dataAccessObject in dataAccessObjects) { var currentExpression = Expression.Equal(parameter, Expression.Constant(dataAccessObject)); if (body == null) { body = currentExpression; } else { body = Expression.OrElse(body, currentExpression); } } if (body == null) { return; } var condition = Expression.Lambda(body, parameter); var expression = (Expression)Expression.Call(null, GetDeleteMethod(typeDescriptor.Type), Expression.Constant(null, typeDescriptor.Type), condition); expression = Evaluator.PartialEval(expression); expression = QueryBinder.Bind(this.DataAccessModel, expression, null, null); expression = SqlObjectOperandComparisonExpander.Expand(expression); expression = SqlQueryProvider.Optimize(expression, this.SqlDatabaseContext.SqlDataTypeProvider.GetTypeForEnums()); this.Delete((SqlDeleteExpression)expression); }
/// <summary> /// Apply mapping to a sub query expression /// </summary> /// <param name="expression"></param> /// <returns></returns> public virtual Expression ApplyMapping(Expression expression) { return(QueryBinder.Bind(this, expression)); }
internal static Expression GetMemberExpression(TranslateContext transContext, Expression root, IProperty property) { if (property is RelationProperty relationProprety) { //所关联的实体类型 var relMetadata = EntityMetadataUnity.GetEntityMetadata(relationProprety.RelationalType); var projection = GetTableQuery(transContext, relMetadata, false, false); Expression parentExp = null, childExp = null; var ship = RelationshipUnity.GetRelationship(relationProprety); if (ship.ThisType != relationProprety.EntityType) { parentExp = projection.Projector; childExp = root; } else { parentExp = root; childExp = projection.Projector; } var where = ship.Keys.Select(r => GetMemberExpression(transContext, parentExp, r.ThisProperty).Equal(GetMemberExpression(transContext, childExp, r.OtherProperty))) .Aggregate(Expression.And); var newAlias = new TableAlias(); var pc = ColumnProjector.ProjectColumns(CanBeColumnExpression, projection.Projector, null, newAlias, projection.Select.Alias); var aggregator = GetAggregator(property.Type, typeof(IEnumerable <>).MakeGenericType(pc.Projector.Type)); var result = new ProjectionExpression( new SelectExpression(newAlias, pc.Columns, projection.Select, where), pc.Projector, aggregator, projection.IsAsync, projection.IsNoTracking ); return(transContext.QueryPolicy.ApplyPolicy(result, property.Info.ReflectionInfo, ex => QueryBinder.Bind(transContext, ex))); } if (root is TableExpression table) { if (property is SubqueryProperty sqProperty) { return(new SubqueryColumnExpression(property.Type, table.Alias, property.Info.FieldName, sqProperty.Subquery)); } else if (property is ISavedProperty) { return(new ColumnExpression(property.Type, table.Alias, property.Name, property.Info)); } } return(QueryBinder.BindMember(root, property.Info.ReflectionInfo)); }
internal static ProjectionExpression GetTableQuery(TranslateContext transContext, EntityMetadata entity, bool isNoTracking, bool isAsync) { var tableAlias = new TableAlias(); var selectAlias = new TableAlias(); var entityType = entity.EntityType; var table = new TableExpression(tableAlias, entity.TableName, entityType); var projector = GetTypeProjection(transContext, table, entity); var pc = ColumnProjector.ProjectColumns(CanBeColumnExpression, projector, null, selectAlias, tableAlias); var proj = new ProjectionExpression( new SelectExpression(selectAlias, pc.Columns, table, null), pc.Projector, isAsync, isNoTracking ); return((ProjectionExpression)transContext.QueryPolicy.ApplyPolicy(proj, entityType, ex => QueryBinder.Bind(transContext, ex))); }
internal Expression GetExecutionPlan(Expression expression) { LambdaExpression lambda = expression as LambdaExpression; if (lambda != null) { expression = lambda.Body; } var translation = expression; translation = PartialEvaluator.Eval(expression, ExpressionHelper.CanBeEvaluatedLocally); translation = FunctionBinder.Bind(this, translation); //translation = PartialEvaluator.Eval(translation, ExpressionHelper.CanBeEvaluatedLocally); translation = QueryBinder.Bind(ExpressionBuilder, this, translation); translation = AggregateRewriter.Rewrite(Dialect, translation); translation = UnusedColumnRemover.Remove(translation); translation = RedundantColumnRemover.Remove(translation); translation = RedundantSubqueryRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); var bound = RelationshipBinder.Bind(ExpressionBuilder, translation); if (bound != translation) { translation = bound; translation = RedundantColumnRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); } translation = ComparisonRewriter.Rewrite(ExpressionBuilder, translation); var rewritten = RelationshipIncluder.Include(ExpressionBuilder, this, translation); if (rewritten != translation) { translation = rewritten; translation = UnusedColumnRemover.Remove(translation); translation = RedundantColumnRemover.Remove(translation); translation = RedundantSubqueryRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); } rewritten = SingletonProjectionRewriter.Rewrite(this.ExpressionBuilder, translation); if (rewritten != translation) { translation = rewritten; translation = UnusedColumnRemover.Remove(translation); translation = RedundantColumnRemover.Remove(translation); translation = RedundantSubqueryRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); } rewritten = ClientJoinedProjectionRewriter.Rewrite(this, translation); if (rewritten != translation) { translation = rewritten; translation = UnusedColumnRemover.Remove(translation); translation = RedundantColumnRemover.Remove(translation); translation = RedundantSubqueryRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); } // translation = this.ExpressionBuilder.Translate(translation); var parameters = lambda != null ? lambda.Parameters : null; Expression provider = Find(expression, parameters, typeof(InternalDbContext)); if (provider == null) { Expression rootQueryable = Find(expression, parameters, typeof(IQueryable)); provider = Expression.Property(rootQueryable, typeof(IQueryable).GetProperty("Provider")); } return(ExecutionBuilder.Build(this.Dialect, this, translation, provider)); }
private PrivateExecuteResult <T> PrivateExecute <T>(Expression expression) { var projectionExpression = expression as SqlProjectionExpression; if (projectionExpression == null) { expression = Evaluator.PartialEval(expression); if (this.RelatedDataAccessObjectContext == null) { expression = QueryBinder.Bind(this.DataAccessModel, expression, null, null); } else { expression = QueryBinder.Bind(this.DataAccessModel, expression, this.RelatedDataAccessObjectContext.ElementType, this.RelatedDataAccessObjectContext.ExtraCondition); } projectionExpression = (SqlProjectionExpression)Optimize(expression, this.SqlDatabaseContext.SqlDataTypeProvider.GetTypeForEnums(), true); } ProjectorCacheInfo cacheInfo; var columns = projectionExpression.Select.Columns.Select(c => c.Name); var formatResult = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(projectionExpression, SqlQueryFormatterOptions.Default); var placeholderValues = PlaceholderValuesCollector.CollectValues(expression); var key = new ProjectorCacheKey(projectionExpression, this.SqlDatabaseContext); var projectorCache = this.SqlDatabaseContext.projectorCache; if (!projectorCache.TryGetValue(key, out cacheInfo)) { var projectionLambda = ProjectionBuilder.Build(this.DataAccessModel, this.SqlDatabaseContext, projectionExpression.Projector, columns); cacheInfo.elementType = projectionLambda.Body.Type; cacheInfo.projector = projectionLambda.Compile(); var aggregates = AggregateFinder.Find(projectionExpression); if (aggregates.Count == 1) { cacheInfo.sqlAggregateType = aggregates.First().AggregateType; } var newCache = new Dictionary <ProjectorCacheKey, ProjectorCacheInfo>(projectorCache, ProjectorCacheEqualityComparer.Default); if (!projectorCache.ContainsKey(key)) { newCache[key] = cacheInfo; } this.SqlDatabaseContext.projectorCache = newCache; } var elementType = TypeHelper.GetElementType(cacheInfo.elementType); var concreteElementType = elementType; if (elementType.IsDataAccessObjectType()) { Type type; TypeHelper.GetElementType(cacheInfo.elementType); elementType = this.DataAccessModel.GetDefinitionTypeFromConcreteType(elementType); concreteElementType = this.DataAccessModel.GetConcreteTypeFromDefinitionType(elementType); if (this.RelatedDataAccessObjectContext == null) { type = typeof(DataAccessObjectProjector <,>); } else { type = typeof(RelatedDataAccessObjectProjector <,>); } return(new PrivateExecuteResult <T> ( (IEnumerable <T>)Activator.CreateInstance ( type.MakeGenericType(elementType, concreteElementType), this, this.DataAccessModel, formatResult, this.SqlDatabaseContext, cacheInfo.projector, this.RelatedDataAccessObjectContext, projectionExpression.SelectFirstType, cacheInfo.sqlAggregateType, projectionExpression.IsDefaultIfEmpty, placeholderValues ), projectionExpression.SelectFirstType, cacheInfo.sqlAggregateType, projectionExpression.IsDefaultIfEmpty, projectionExpression.DefaultValueExpression )); } else { return(new PrivateExecuteResult <T> ( (IEnumerable <T>)Activator.CreateInstance ( typeof(ObjectProjector <,>).MakeGenericType(elementType, concreteElementType), this, this.DataAccessModel, formatResult, this.SqlDatabaseContext, cacheInfo.projector, this.RelatedDataAccessObjectContext, projectionExpression.SelectFirstType, cacheInfo.sqlAggregateType, projectionExpression.IsDefaultIfEmpty, placeholderValues ), projectionExpression.SelectFirstType, cacheInfo.sqlAggregateType, projectionExpression.IsDefaultIfEmpty, projectionExpression.DefaultValueExpression )); } }
private Expression TranslateInternal(TranslateContext transContext, Expression expression) { var translation = QueryBinder.Bind(transContext, expression); translation = LogicalDeleteFlagRewriter.Rewrite(translation); translation = GlobalQueryPolicyRewriter.Rewrite(translation); translation = AggregateRewriter.Rewrite(translation); translation = UnusedColumnRemover.Remove(translation); translation = RedundantColumnRemover.Remove(translation); translation = RedundantSubqueryRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); var bound = RelationshipBinder.Bind(transContext, translation); if (bound != translation) { translation = bound; translation = RedundantColumnRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); } translation = ComparisonRewriter.Rewrite(translation); Expression rewritten; if (transContext.QueryPolicy != null) { rewritten = RelationshipIncluder.Include(transContext, translation); if (rewritten != translation) { translation = rewritten; translation = UnusedColumnRemover.Remove(translation); translation = RedundantColumnRemover.Remove(translation); translation = RedundantSubqueryRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); } } rewritten = SingletonProjectionRewriter.Rewrite(translation); if (rewritten != translation) { translation = rewritten; translation = UnusedColumnRemover.Remove(translation); translation = RedundantColumnRemover.Remove(translation); translation = RedundantSubqueryRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); } rewritten = ClientJoinedProjectionRewriter.Rewrite(translation); if (rewritten != translation) { translation = rewritten; translation = UnusedColumnRemover.Remove(translation); translation = RedundantColumnRemover.Remove(translation); translation = RedundantSubqueryRemover.Remove(translation); translation = RedundantJoinRemover.Remove(translation); } translation = BuildExpression(translation); return(translation); }