/// <summary> /// Main entry point for the class. Builds or retrive from cache a SQL query corresponding to given Expressions /// </summary> /// <param name="expressions"></param> /// <param name="queryContext"></param> /// <returns></returns> public SelectQuery GetSelectQuery(ExpressionChain expressions, QueryContext queryContext) { SelectQuery query = null; if (queryContext.DataContext.QueryCacheEnabled) { query = GetFromSelectCache(expressions); } if (query == null) { Profiler.At("START: GetSelectQuery(), building Expression query"); var expressionsQuery = BuildExpressionQuery(expressions, queryContext); Profiler.At("END: GetSelectQuery(), building Expression query"); Profiler.At("START: GetSelectQuery(), building Sql query"); query = BuildSqlQuery(expressionsQuery, queryContext); Profiler.At("END: GetSelectQuery(), building Sql query"); if (queryContext.DataContext.QueryCacheEnabled) { SetInSelectCache(expressions, query); } } return(query); }
protected virtual SelectExpression TranslateSelectExpression(LinqCommand cmd, TranslationContext context) { if (cmd.SelectExpression != null) //special case for Md1, Select is provided in command { context.CurrentSelect = cmd.SelectExpression; return(cmd.SelectExpression); } var linqExpr = cmd.Lambda.Body; var exprChain = ExpressionChain.Build(linqExpr); var tableExpr = _translator.ExtractFirstTable(exprChain[0], context); var selectExpression = _translator.Analyze(exprChain, tableExpr, context); // Check expected type - it will be used for final result conversion if query returns a single value (like Count() query) var resultType = exprChain[exprChain.Count - 1].Type; if (resultType.IsGenericQueryable()) { resultType = selectExpression.Type; } _translator.BuildSelectResultReaderAndCutOutSql(selectExpression, context, resultType); BuildOffsetsAndLimits(context); // then prepare Parts for SQL translation CheckTablesAlias(context); CheckColumnNamesAliases(context); cmd.SelectExpression = context.CurrentSelect; return(context.CurrentSelect); }
public SelectQuery GetFromSelectCache(ExpressionChain expressions) { SelectQuery selectQuery; selectQueries.TryGetValue(expressions, out selectQuery); return(selectQuery); }
public SelectQuery GetFromSelectCache(ExpressionChain expressions) { SelectQuery selectQuery; lock (selectQueries) selectQueries.TryGetValue(expressions, out selectQuery); return selectQuery; }
public void ExpressionChain_And_FourArguments_Success() { Expression <Func <Person, bool> > f1 = x => x.Id > 0; Expression <Func <Person, bool> > f2 = x => x.Category == "CATEGORY 1"; Expression <Func <Person, bool> > f3 = x => x.Name == "Dude"; Expression <Func <Person, bool> > f4 = x => x.City == "LA"; Expression <Func <Person, bool> > mergedExpression = ExpressionChain.And(f1, f2, f3, f4); IQueryable <Person> mockups = new List <Person> { new Person { Id = 0, Category = "CATEGORY 1", Name = "Duderino", City = "LA" }, // Miss: Id <= 0 new Person { Id = 1, Category = "CATEGORY 1", Name = "Dude", City = "LA" }, // Hit new Person { Id = 2, Category = "CATEGORY 1", Name = "Dude", City = "NY" }, // Miss:City != LA new Person { Id = 3, Category = "CATEGORY 2", Name = "Dude", City = "LA" }, // Miss: Category }.AsQueryable(); Assert.IsTrue(mockups.Where(mergedExpression).Count() == 1); }
public void ExpressionChain_And_ThreeArguments_Success() { Expression <Func <Person, bool> > f1 = x => x.Id > 0; Expression <Func <Person, bool> > f2 = x => x.Category == "CATEGORY 1"; Expression <Func <Person, bool> > f3 = x => x.Name == "Dude"; Expression <Func <Person, bool> > mergedExpression = ExpressionChain.And(f1, f2, f3); IQueryable <Person> mockups = new List <Person> { new Person { Id = 0, Category = "CATEGORY 1", Name = "Duderino" }, new Person { Id = 1, Category = "CATEGORY 1", Name = "Dude" }, new Person { Id = 2, Category = "CATEGORY 1", Name = "Dude" }, new Person { Id = 3, Category = "CATEGORY 2", Name = "Dude" }, }.AsQueryable(); Assert.IsTrue(mockups.Where(mergedExpression).Count() == 2); }
public void ExpressionChain_And_OneArgument_ReturnsSame() { Expression <Func <Person, bool> > f1 = x => x.Id > 0; Expression <Func <Person, bool> > mergedExpression = ExpressionChain.And(f1); Assert.IsTrue(mergedExpression == f1); }
public void ExpressionChain_Or_FiveArguments_Success() { Expression <Func <Person, bool> > f1 = x => x.Id > 0; Expression <Func <Person, bool> > f2 = x => x.Category == "CATEGORY 1"; Expression <Func <Person, bool> > f3 = x => x.Name == "Dude"; Expression <Func <Person, bool> > f4 = x => x.City == "LA"; Expression <Func <Person, bool> > f5 = x => x.IsGolfer == true; Expression <Func <Person, bool> > mergedExpression = ExpressionChain.Or(f1, f2, f3, f4, f5); IQueryable <Person> mockups = new List <Person> { new Person { Id = 0, Category = "CATEGORY 1", Name = "Duderino", City = "NY", IsGolfer = true }, new Person { Id = 1, Category = "CATEGORY 1", Name = "Dude", City = "LA", IsGolfer = true }, new Person { Id = 2, Category = "CATEGORY 1", Name = "Dude", City = "LA", IsGolfer = true }, new Person { Id = 3, Category = "CATEGORY 2", Name = "Dude", City = "LA", IsGolfer = true }, }.AsQueryable(); Assert.IsTrue(mockups.Where(mergedExpression).Count() == 4); }
/// <summary> /// Main entry point for the class. Builds or retrive from cache a SQL query corresponding to given Expressions /// </summary> /// <param name="expressions"></param> /// <param name="queryContext"></param> /// <returns></returns> public SelectQuery GetSelectQuery(ExpressionChain expressions, QueryContext queryContext) { SelectQuery query = null; if (queryContext.DataContext.QueryCacheEnabled) { query = GetFromSelectCache(expressions); } if (query == null) { Profiler.At("START: GetSelectQuery(), building Expression query"); var expressionsQuery = BuildExpressionQuery(expressions, queryContext); Profiler.At("END: GetSelectQuery(), building Expression query"); Profiler.At("START: GetSelectQuery(), building Sql query"); query = BuildSqlQuery(expressionsQuery, queryContext); Profiler.At("END: GetSelectQuery(), building Sql query"); if (queryContext.DataContext.QueryCacheEnabled) { SetInSelectCache(expressions, query); } } else if (query.InputParameters.Count > 0) { Profiler.At("START: GetSelectQuery(), building Expression parameters of cached query"); var parameters = BuildExpressionParameters(expressions, queryContext); query = new SelectQuery(queryContext.DataContext, query.Sql, parameters, query.RowObjectCreator, query.ExecuteMethodName); Profiler.At("END: GetSelectQuery(), building Expression parameters of cached query"); } return(query); }
public void SimpleSelector_should_work() { var selector = ExpressionChain <User> .New(u => u.TwitterUri); Assert.True(selector.Contains(u => u.TwitterUri)); Assert.Equal("TwitterUri", selector.Name); }
/// <summary> /// Builds the ExpressionQuery: /// - parses Expressions and builds row creator /// - checks names unicity /// </summary> /// <param name="expressions"></param> /// <param name="queryContext"></param> /// <returns></returns> protected virtual ExpressionQuery BuildExpressionQuery(ExpressionChain expressions, QueryContext queryContext) { var builderContext = new BuilderContext(queryContext); BuildExpressionQuery(expressions, builderContext); CheckTablesAlias(builderContext); CheckParametersAlias(builderContext); return builderContext.ExpressionQuery; }
protected virtual void SetInSelectCache(ExpressionChain expressions, SelectQuery query) { var cache = QueryCache; // Lytico: dont cache the dataContext. It is a short living object and should not be cached! query = new SelectQuery(null, query.Sql, query.InputParameters, query.RowObjectCreator, query.ExecuteMethodName); cache.SetInSelectCache(expressions, query); }
/// <summary> /// Builds the ExpressionQuery: /// - parses Expressions and builds row creator /// - checks names unicity /// </summary> /// <param name="expressions"></param> /// <param name="queryContext"></param> /// <returns></returns> protected virtual ExpressionQuery BuildExpressionQuery(ExpressionChain expressions, QueryContext queryContext) { var builderContext = new BuilderContext(queryContext); BuildExpressionQuery(expressions, builderContext); CheckTablesAlias(builderContext); CheckParametersAlias(builderContext); return(builderContext.ExpressionQuery); }
public SelectQuery GetSelectQuery(ExpressionChain expressions, QueryContext queryContext) { Profiler.At("START: GetSelectQuery(), building Expression query"); var builderContext = BuildExpressionQuery( expressions, queryContext, !queryContext.DataContext.QueryCacheEnabled); Profiler.At("END: GetSelectQuery(), building Expression query"); Profiler.At("START: GetSelectQuery(), building Sql query"); var sql = SqlBuilder.BuildSelect(builderContext.ExpressionQuery, queryContext); Profiler.At("END: GetSelectQuery(), building Sql query"); // we cache the sql var cb = new StringBuilder(sql.ToString()); foreach (var e in expressions) { cb.Append(e); } var cacheKey = cb.ToString(); // correct, but very time consuming: // AND the reader, cause it is possible to have same sql and different reader-parameters //= string.Concat(sql,builderContext.ExpressionQuery.Select.Reader); if (queryContext.DataContext.QueryCacheEnabled) { Delegate rowObjectCreator = null; if (selectRowCreators.TryGetValue(cacheKey, out rowObjectCreator)) { builderContext.ExpressionQuery.RowObjectCreator = rowObjectCreator; } } if (builderContext.ExpressionQuery.RowObjectCreator == null) { // finally, compile our object creation method; this is the Time-Expensive stuff CompileRowCreator(builderContext); if (queryContext.DataContext.QueryCacheEnabled) { selectRowCreators.MergeSafe(cacheKey, builderContext.ExpressionQuery.RowObjectCreator); } } var query = new SelectQuery( queryContext.DataContext, sql, builderContext.ExpressionQuery.Parameters, builderContext.ExpressionQuery.RowObjectCreator, builderContext.ExpressionQuery.Select.ExecuteMethodName); return(query); }
/// <summary> /// Builds the ExpressionQuery: /// - parses Expressions and builds row creator /// - checks names unicity /// </summary> /// <param name="expressions"></param> /// <param name="queryContext"></param> /// <returns></returns> protected virtual BuilderContext BuildExpressionQuery(ExpressionChain expressions, QueryContext queryContext, bool compile) { var builderContext = new BuilderContext(queryContext); BuildExpressionQuery(expressions, builderContext, compile); CheckTablesAlias(builderContext); CheckParametersAlias(builderContext); return(builderContext); }
public void ComparingTheSameReferencedPropertyShouldWork() { var dictionary = new Dictionary <IExpression, int>(new RddExpressionEqualityComparer()); var p1 = ExpressionChain <FakeClass> .New(fc => fc.A); var p1Val = 42; dictionary.Add(p1, p1Val); Assert.Equal(p1Val, dictionary[p1]); }
IList <InputParameterExpression> BuildExpressionParameters(ExpressionChain expressions, QueryContext queryContext) { var builderContext = new BuilderContext(queryContext); var previousExpression = ExpressionDispatcher.CreateTableExpression(expressions.Expressions[0], builderContext); previousExpression = BuildExpressionQuery(expressions, previousExpression, builderContext); BuildOffsetsAndLimits(builderContext); // then prepare Parts for SQL translation PrepareSqlOperands(builderContext); return(builderContext.ExpressionQuery.Parameters); }
public static void TestExpressionChainEnumerator() { var be = (BinaryExpressionSyntax)ParseExpression("a + b + c"); var be2 = (BinaryExpressionSyntax)be.Left; ExpressionChain.Enumerator en = new ExpressionChain(be).GetEnumerator(); Assert.True(en.MoveNext() && en.Current == be2.Left); Assert.True(en.MoveNext() && en.Current == be2.Right); Assert.True(en.MoveNext() && en.Current == be.Right); Assert.True(!en.MoveNext()); }
public Expression Analyze(ExpressionChain expressionChain, Expression parameter, TranslationContext context) { Expression resultExpression = parameter; Expression last = expressionChain.Last(); foreach (Expression expr in expressionChain) { if (expr == last) context.IsExternalInExpressionChain = true; resultExpression = this.Analyze(expr, resultExpression, context); } return resultExpression; }
public void ComparingPropertiesWithTheSameNameFromTwoDifferentClassesShouldFail() { var dictionary = new Dictionary <IExpression, int>(new RddExpressionEqualityComparer()); var p1 = ExpressionChain <FakeClass> .New(fc => fc.A); var p1Val = 42; dictionary.Add(p1, p1Val); var p2 = ExpressionChain <FakeClass2> .New(fc => fc.A); Assert.False(dictionary.ContainsKey(p2)); }
public void ComparingPropertyInstancesWithDifferentEntityNameButSamePropertyShouldWork() { var dictionary = new Dictionary <IExpression, int>(new RddExpressionEqualityComparer()); var p1 = ExpressionChain <FakeClass> .New(fc => fc.A); var p1Val = 42; dictionary.Add(p1, p1Val); var p2 = ExpressionChain <FakeClass> .New(fakeClass => fakeClass.A); Assert.Equal(p1Val, dictionary[p2]); }
/// <summary> /// Builds and chains the provided Expressions /// </summary> /// <param name="expressions"></param> /// <param name="builderContext"></param> protected virtual void BuildExpressionQuery(ExpressionChain expressions, BuilderContext builderContext) { var previousExpression = ExpressionDispatcher.CreateTableExpression(expressions.Expressions[0], builderContext); previousExpression = BuildExpressionQuery(expressions, previousExpression, builderContext); BuildOffsetsAndLimits(builderContext); // then prepare Parts for SQL translation PrepareSqlOperands(builderContext); // now, we optimize anything we can OptimizeQuery(builderContext); // finally, compile our object creation method CompileRowCreator(builderContext); // in the very end, we keep the SELECT clause builderContext.ExpressionQuery.Select = builderContext.CurrentSelect; }
public static void TestExpressionChainEnumerator_WithSpan4() { const string s = @" class C { void M(string a, string b) { string s = a + [|b|]; } }"; TextSpanParserResult result = TextSpanParser.Default.GetSpans(s); BinaryExpressionSyntax be = CSharpSyntaxTree.ParseText(result.Text).GetRoot().FirstDescendant <BinaryExpressionSyntax>(); ExpressionChain.Enumerator en = new ExpressionChain(be, result.Spans[0].Span).GetEnumerator(); Assert.True(en.MoveNext() && en.Current == be.Right); Assert.True(!en.MoveNext()); }
public static void TestExpressionChainEnumerator_WithSpan4() { const string s = @" class C { void M(string a, string b) { string s = a + [|b|]; } }"; var code = TestCode.Parse(s); BinaryExpressionSyntax be = CSharpSyntaxTree.ParseText(code.Value).GetRoot().FirstDescendant <BinaryExpressionSyntax>(); ExpressionChain.Enumerator en = new ExpressionChain(be, code.Spans[0]).GetEnumerator(); Assert.True(en.MoveNext() && en.Current == be.Right); Assert.True(!en.MoveNext()); }
public static void TestExpressionChainReversedEnumerator_WithSpan5() { const string s = @" class C { void M(string a, string b) { string s = [|a|] + b; } }"; TextParserResult result = TextParser.GetSpans(s); BinaryExpressionSyntax be = CSharpSyntaxTree.ParseText(result.Text).GetRoot().FirstDescendant <BinaryExpressionSyntax>(); ExpressionChain.Reversed.Enumerator en = new ExpressionChain(be, result.Spans[0].Span).Reverse().GetEnumerator(); Assert.True(en.MoveNext() && en.Current == be.Left); Assert.True(!en.MoveNext()); }
protected virtual SelectExpression TranslateSelectExpression(Expression linqExpr, TranslationContext context) { var exprChain = ExpressionChain.Build(linqExpr); var tableExpr = _translator.ExtractFirstTable(exprChain[0], context); var selectExpression = _translator.Analyze(exprChain, tableExpr, context); // Check expected type - it will be used for final result conversion if query returns a single value (like Count() query) var resultType = exprChain[exprChain.Count - 1].Type; if (resultType.IsGenericQueryable()) { resultType = selectExpression.Type; } _translator.BuildSelectResultReaderAndCutOutSql(selectExpression, context, resultType); BuildOffsetsAndLimits(context); // then prepare Parts for SQL translation CheckTablesAlias(context); CheckColumnNamesAliases(context); return(context.CurrentSelect); }
public static void TestExpressionChainReversedEnumerator_WithSpan2() { const string s = @" class C { void M(string a, string b, string c, string d) { string s = a + b + [|c + d|]; } }"; SpanParserResult result = SpanParser.Default.GetSpans(s); BinaryExpressionSyntax be = CSharpSyntaxTree.ParseText(result.Text).GetRoot().FirstDescendant <BinaryExpressionSyntax>(); var be2 = (BinaryExpressionSyntax)be.Left; ExpressionChain.Reversed.Enumerator en = new ExpressionChain(be, result.Spans[0].Span).Reverse().GetEnumerator(); Assert.True(en.MoveNext() && en.Current == be.Right); Assert.True(en.MoveNext() && en.Current == be2.Right); Assert.True(!en.MoveNext()); }
public static void TestExpressionChainReversedEnumerator_WithSpan() { const string s = @" class C { void M(string a, string b, string c) { string s = [|a + b + c|]; } }"; var code = TestCode.Parse(s); BinaryExpressionSyntax be = CSharpSyntaxTree.ParseText(code.Value).GetRoot().FirstDescendant <BinaryExpressionSyntax>(); var be2 = (BinaryExpressionSyntax)be.Left; ExpressionChain.Reversed.Enumerator en = new ExpressionChain(be, code.Spans[0]).Reverse().GetEnumerator(); Assert.True(en.MoveNext() && en.Current == be.Right); Assert.True(en.MoveNext() && en.Current == be2.Right); Assert.True(en.MoveNext() && en.Current == be2.Left); Assert.True(!en.MoveNext()); }
/// <summary> /// Builds and chains the provided Expressions /// </summary> /// <param name="expressionChain"></param> /// <param name="context"></param> protected virtual SelectExpression BuildSelectExpression(ExpressionChain expressionChain, TranslationContext context) { var tableExpr = _translator.ExtractFirstTable(expressionChain[0], context); BuildSelectExpression(expressionChain, tableExpr, context); BuildOffsetsAndLimits(context); // then prepare Parts for SQL translation CheckTablesAlias(context); CheckColumnNamesAliases(context); // now, we optimize anything we can OptimizeQuery(context); context.CurrentSelect.CommandInfo = context.Command.Info; //copy command info to final select // in the very end, we keep the SELECT clause return context.CurrentSelect; }
public void SetInSelectCache(ExpressionChain expressions, SelectQuery sqlSelectQuery) { selectQueries.MergeSafe(expressions, sqlSelectQuery); }
public bool HasProperty <TProp>(Expression <Func <TEntity, TProp> > expression) { var selector = ExpressionChain <TEntity> .New(expression); return(ContainsPath(_structure, selector)); }
/// <summary> /// Main entry point for the class. Builds or retrive from cache a SQL query corresponding to given Expressions /// </summary> /// <param name="expressions"></param> /// <param name="queryContext"></param> /// <returns></returns> public SelectQuery GetSelectQuery(ExpressionChain expressions, QueryContext queryContext) { var query = GetFromSelectCache(expressions); if (query == null) { var timer = new Stopwatch(); timer.Start(); var expressionsQuery = BuildExpressionQuery(expressions, queryContext); timer.Stop(); long expressionBuildTime = timer.ElapsedMilliseconds; timer.Reset(); timer.Start(); query = BuildSqlQuery(expressionsQuery, queryContext); timer.Stop(); long sqlBuildTime = timer.ElapsedMilliseconds; queryContext.DataContext.Logger.Write(Level.Debug, "Select Expression build: {0}ms", expressionBuildTime); queryContext.DataContext.Logger.Write(Level.Debug, "Select SQL build: {0}ms", sqlBuildTime); queryContext.DataContext.Logger.Write(Level.Debug, "Select SQL: {0}", query.Sql); SetInSelectCache(expressions, query); } return query; }
protected virtual SelectQuery GetFromSelectCache(ExpressionChain expressions) { var cache = QueryCache; lock (cache) return cache.GetFromSelectCache(expressions); }
/// <summary> /// Builds the ExpressionQuery main Expression, given a Table (or projection) expression /// </summary> /// <param name="expressions"></param> /// <param name="tableExpression"></param> /// <param name="builderContext"></param> /// <returns></returns> protected Expression BuildExpressionQuery(ExpressionChain expressions, Expression tableExpression, BuilderContext builderContext) { var last = expressions.Last(); foreach (var expression in expressions) { if (expression == last) builderContext.IsExternalInExpressionChain = true; builderContext.QueryContext.DataContext.Logger.WriteExpression(Level.Debug, expression); // Convert linq Expressions to QueryOperationExpressions and QueryConstantExpressions // Query expressions language identification var currentExpression = ExpressionLanguageParser.Parse(expression, builderContext); // Query expressions query identification currentExpression = ExpressionDispatcher.Analyze(currentExpression, tableExpression, builderContext); tableExpression = currentExpression; } ExpressionDispatcher.BuildSelect(tableExpression, builderContext); return tableExpression; }
/// <summary> /// Builds the ExpressionQuery main Expression, given a Table (or projection) expression /// </summary> /// <param name="expressions"></param> /// <param name="tableExpression"></param> /// <param name="builderContext"></param> /// <returns></returns> protected Expression BuildExpressionQuery(ExpressionChain expressions, Expression tableExpression, BuilderContext builderContext) { tableExpression = ExpressionDispatcher.Analyze(expressions, tableExpression, builderContext); ExpressionDispatcher.BuildSelect(tableExpression, builderContext); return tableExpression; }
protected virtual ExpressionQuery BuildExpressionQuery(ExpressionChain expressions, QueryContext queryContext) { return(BuildExpressionQuery(expressions, queryContext, true).ExpressionQuery); }
public void SetInSelectCache(ExpressionChain expressions, SelectQuery sqlSelectQuery) { lock (selectQueries) selectQueries[expressions] = sqlSelectQuery; }
protected virtual SelectQuery GetFromSelectCache(ExpressionChain expressions) { var cache = QueryCache; return(cache.GetFromSelectCache(expressions)); }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, BinaryExpressionSyntax binaryExpression) { SyntaxToken operatorToken = binaryExpression.OperatorToken; if (context.IsRefactoringEnabled(RefactoringIdentifiers.InvertOperator) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(operatorToken) && InvertOperatorRefactoring.CanBeInverted(operatorToken)) { context.RegisterRefactoring( "Invert operator", cancellationToken => InvertOperatorRefactoring.RefactorAsync(context.Document, operatorToken, cancellationToken), RefactoringIdentifiers.InvertOperator); } if (context.Span.IsEmptyAndContainedInSpan(operatorToken)) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.InvertBinaryExpression)) { InvertBinaryExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.SwapBinaryOperands)) { SwapBinaryOperandsRefactoring.ComputeRefactoring(context, binaryExpression); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.FormatBinaryExpression)) { FormatBinaryExpressionRefactoring.ComputeRefactorings(context, binaryExpression); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExpandCoalesceExpression) && operatorToken.Span.Contains(context.Span)) { ExpandCoalesceExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ExtractExpressionFromCondition, RefactoringIdentifiers.JoinStringExpressions, RefactoringIdentifiers.UseStringBuilderInsteadOfConcatenation) && !context.Span.IsEmpty && binaryExpression.IsKind(SyntaxKind.AddExpression, SyntaxKind.LogicalAndExpression, SyntaxKind.LogicalOrExpression)) { ExpressionChain chain = binaryExpression.AsChain(context.Span); ExpressionChain.Enumerator en = chain.GetEnumerator(); if (en.MoveNext() && en.MoveNext()) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExtractExpressionFromCondition)) { ExtractConditionRefactoring.ComputeRefactoring(context, chain); } if (binaryExpression.IsKind(SyntaxKind.AddExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); StringConcatenationExpressionInfo concatenationInfo = SyntaxInfo.StringConcatenationExpressionInfo(chain, semanticModel, context.CancellationToken); if (concatenationInfo.Success) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.JoinStringExpressions)) { JoinStringExpressionsRefactoring.ComputeRefactoring(context, concatenationInfo); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.UseStringBuilderInsteadOfConcatenation)) { UseStringBuilderInsteadOfConcatenationRefactoring.ComputeRefactoring(context, concatenationInfo); } } } } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceAsWithCast) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(binaryExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (ReplaceAsWithCastAnalysis.IsFixable(binaryExpression, semanticModel, context.CancellationToken)) { context.RegisterRefactoring( ReplaceAsWithCastRefactoring.Title, cancellationToken => ReplaceAsWithCastRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken), RefactoringIdentifiers.ReplaceAsWithCast); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.InvertIsExpression)) { InvertIsExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.Span.IsContainedInSpanOrBetweenSpans(operatorToken)) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceEqualsExpressionWithStringEquals)) { await ReplaceEqualsExpressionWithStringEqualsRefactoring.ComputeRefactoringAsync(context, binaryExpression).ConfigureAwait(false); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ReplaceEqualsExpressionWithStringIsNullOrEmpty, RefactoringIdentifiers.ReplaceEqualsExpressionWithStringIsNullOrWhiteSpace)) { await ReplaceEqualsExpressionRefactoring.ComputeRefactoringsAsync(context, binaryExpression).ConfigureAwait(false); } } }
/// <summary> /// Builds and chains the provided Expressions /// </summary> /// <param name="expressions"></param> /// <param name="builderContext"></param> protected virtual void BuildExpressionQuery(ExpressionChain expressions, BuilderContext builderContext) { var previousExpression = ExpressionDispatcher.CreateTableExpression(expressions.Expressions[0], builderContext); previousExpression = BuildExpressionQuery(expressions, previousExpression, builderContext); BuildOffsetsAndLimits(builderContext); // then prepare parts for SQL translation PrepareSqlOperands(builderContext); // now, we optimize anything we can OptimizeQuery(builderContext); // finally, compile our object creation method CompileRowCreator(builderContext); // in the very end, we keep the SELECT clause builderContext.ExpressionQuery.Select = builderContext.CurrentSelect; }
/// <summary> /// Main entry point for the class. Builds or retrive from cache a SQL query corresponding to given Expressions /// </summary> /// <param name="expressions"></param> /// <param name="queryContext"></param> /// <returns></returns> public SelectQuery GetSelectQuery(ExpressionChain expressions, QueryContext queryContext) { SelectQuery query = null; if (queryContext.DataContext.QueryCacheEnabled) { query = GetFromSelectCache(expressions); } if (query == null) { Profiler.At("START: GetSelectQuery(), building Expression query"); var expressionsQuery = BuildExpressionQuery(expressions, queryContext); Profiler.At("END: GetSelectQuery(), building Expression query"); Profiler.At("START: GetSelectQuery(), building Sql query"); query = BuildSqlQuery(expressionsQuery, queryContext); Profiler.At("END: GetSelectQuery(), building Sql query"); if (queryContext.DataContext.QueryCacheEnabled) { SetInSelectCache(expressions, query); } } else if (query.InputParameters.Count > 0) { Profiler.At("START: GetSelectQuery(), building Expression parameters of cached query"); var parameters = BuildExpressionParameters(expressions, queryContext); query = new SelectQuery(queryContext.DataContext, query.Sql, parameters, query.RowObjectCreator, query.ExecuteMethodName); Profiler.At("END: GetSelectQuery(), building Expression parameters of cached query"); } return query; }
public virtual SelectExpression BuildSelectExpression(ExpressionChain expressions, Expression tableExpression, BuilderContext builderContext) { BuildExpressionQuery(expressions, tableExpression, builderContext); return builderContext.CurrentSelect; }
IList<InputParameterExpression> BuildExpressionParameters(ExpressionChain expressions, QueryContext queryContext) { var builderContext = new BuilderContext(queryContext); var previousExpression = ExpressionDispatcher.CreateTableExpression(expressions.Expressions[0], builderContext); previousExpression = BuildExpressionQuery(expressions, previousExpression, builderContext); BuildOffsetsAndLimits(builderContext); // then prepare Parts for SQL translation PrepareSqlOperands(builderContext); return builderContext.ExpressionQuery.Parameters; }
protected virtual void SetInSelectCache(ExpressionChain expressions, SelectQuery sqlSelectQuery) { var cache = QueryCache; lock (cache) cache.SetInSelectCache(expressions, sqlSelectQuery); }
/// <summary> /// Builds the ExpressionQuery main Expression, given a Table (or projection) expression /// </summary> /// <param name="expressions"></param> /// <param name="tableExpression"></param> /// <param name="context"></param> /// <returns></returns> protected Expression BuildSelectExpression(ExpressionChain expressions, Expression tableExpression, TranslationContext context) { // Check expected type - it will be used for final result conversion if query returns a single value (like Count() query) var resultType = expressions[expressions.Count - 1].Type; if (resultType.IsGenericQueryable()) resultType = null; var selectExpression = _translator.Analyze(expressions, tableExpression, context); _translator.BuildSelect(selectExpression, context, resultType); return selectExpression; }
/// <summary> /// Main entry point for the class. Builds or retrive from cache a SQL query corresponding to given Expressions /// </summary> /// <param name="expressions"></param> /// <param name="queryContext"></param> /// <returns></returns> public SelectQuery GetSelectQuery(ExpressionChain expressions, QueryContext queryContext) { SelectQuery query = null; if (queryContext.DataContext.QueryCacheEnabled) { query = GetFromSelectCache(expressions); } if (query == null) { Profiler.At("START: GetSelectQuery(), building Expression query"); var expressionsQuery = BuildExpressionQuery(expressions, queryContext); Profiler.At("END: GetSelectQuery(), building Expression query"); Profiler.At("START: GetSelectQuery(), building Sql query"); query = BuildSqlQuery(expressionsQuery, queryContext); Profiler.At("END: GetSelectQuery(), building Sql query"); if (queryContext.DataContext.QueryCacheEnabled) { SetInSelectCache(expressions, query); } } return query; }