4
4
using System ;
5
5
using System . Collections ;
6
6
using System . Collections . Generic ;
7
+ using System . Text ;
7
8
using System . Threading ;
8
9
using System . Threading . Tasks ;
10
+ using Microsoft . EntityFrameworkCore . Cosmos . Storage . Internal ;
9
11
using Microsoft . EntityFrameworkCore . Diagnostics ;
10
12
using Microsoft . EntityFrameworkCore . Query ;
11
13
using Newtonsoft . Json . Linq ;
12
14
13
15
namespace Microsoft . EntityFrameworkCore . Cosmos . Query . Internal
14
16
{
17
+ /// <summary>
18
+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
19
+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
20
+ /// any release. You should only use it directly in your code with extreme caution and knowing that
21
+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
22
+ /// </summary>
15
23
public partial class CosmosShapedQueryCompilingExpressionVisitor
16
24
{
17
- private sealed class QueryingEnumerable < T > : IEnumerable < T > , IAsyncEnumerable < T >
25
+ private sealed class QueryingEnumerable < T > : IEnumerable < T > , IAsyncEnumerable < T > , IQueryingEnumerable
18
26
{
19
27
private readonly CosmosQueryContext _cosmosQueryContext ;
20
28
private readonly ISqlExpressionFactory _sqlExpressionFactory ;
@@ -48,26 +56,44 @@ public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToke
48
56
public IEnumerator < T > GetEnumerator ( ) => new Enumerator ( this ) ;
49
57
IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
50
58
59
+ private CosmosSqlQuery GenerateQuery ( )
60
+ => _querySqlGeneratorFactory . Create ( ) . GetSqlQuery (
61
+ ( SelectExpression ) new InExpressionValuesExpandingExpressionVisitor (
62
+ _sqlExpressionFactory ,
63
+ _cosmosQueryContext . ParameterValues )
64
+ . Visit ( _selectExpression ) ,
65
+ _cosmosQueryContext . ParameterValues ) ;
66
+
67
+ public string ToQueryString ( )
68
+ {
69
+ var sqlQuery = GenerateQuery ( ) ;
70
+ if ( sqlQuery . Parameters . Count == 0 )
71
+ {
72
+ return sqlQuery . Query ;
73
+ }
74
+
75
+ var builder = new StringBuilder ( ) ;
76
+ foreach ( var parameter in sqlQuery . Parameters )
77
+ {
78
+ builder
79
+ . Append ( "-- " )
80
+ . Append ( parameter . Name )
81
+ . Append ( "='" )
82
+ . Append ( parameter . Value )
83
+ . AppendLine ( "'" ) ;
84
+ }
85
+
86
+ return builder . Append ( sqlQuery . Query ) . ToString ( ) ;
87
+ }
88
+
51
89
private sealed class Enumerator : IEnumerator < T >
52
90
{
91
+ private readonly QueryingEnumerable < T > _queryingEnumerable ;
53
92
private IEnumerator < JObject > _enumerator ;
54
- private readonly CosmosQueryContext _cosmosQueryContext ;
55
- private readonly SelectExpression _selectExpression ;
56
- private readonly Func < QueryContext , JObject , T > _shaper ;
57
- private readonly ISqlExpressionFactory _sqlExpressionFactory ;
58
- private readonly IQuerySqlGeneratorFactory _querySqlGeneratorFactory ;
59
- private readonly Type _contextType ;
60
- private readonly IDiagnosticsLogger < DbLoggerCategory . Query > _logger ;
61
93
62
94
public Enumerator ( QueryingEnumerable < T > queryingEnumerable )
63
95
{
64
- _cosmosQueryContext = queryingEnumerable . _cosmosQueryContext ;
65
- _shaper = queryingEnumerable . _shaper ;
66
- _selectExpression = queryingEnumerable . _selectExpression ;
67
- _sqlExpressionFactory = queryingEnumerable . _sqlExpressionFactory ;
68
- _querySqlGeneratorFactory = queryingEnumerable . _querySqlGeneratorFactory ;
69
- _contextType = queryingEnumerable . _contextType ;
70
- _logger = queryingEnumerable . _logger ;
96
+ _queryingEnumerable = queryingEnumerable ;
71
97
}
72
98
73
99
public T Current { get ; private set ; }
@@ -78,19 +104,15 @@ public bool MoveNext()
78
104
{
79
105
try
80
106
{
81
- using ( _cosmosQueryContext . ConcurrencyDetector . EnterCriticalSection ( ) )
107
+ using ( _queryingEnumerable . _cosmosQueryContext . ConcurrencyDetector . EnterCriticalSection ( ) )
82
108
{
83
109
if ( _enumerator == null )
84
110
{
85
- var selectExpression = ( SelectExpression ) new InExpressionValuesExpandingExpressionVisitor (
86
- _sqlExpressionFactory , _cosmosQueryContext . ParameterValues ) . Visit ( _selectExpression ) ;
87
-
88
- var sqlQuery = _querySqlGeneratorFactory . Create ( ) . GetSqlQuery (
89
- selectExpression , _cosmosQueryContext . ParameterValues ) ;
111
+ var sqlQuery = _queryingEnumerable . GenerateQuery ( ) ;
90
112
91
- _enumerator = _cosmosQueryContext . CosmosClient
113
+ _enumerator = _queryingEnumerable . _cosmosQueryContext . CosmosClient
92
114
. ExecuteSqlQuery (
93
- _selectExpression . Container ,
115
+ _queryingEnumerable . _selectExpression . Container ,
94
116
sqlQuery )
95
117
. GetEnumerator ( ) ;
96
118
}
@@ -99,15 +121,15 @@ public bool MoveNext()
99
121
100
122
Current
101
123
= hasNext
102
- ? _shaper ( _cosmosQueryContext , _enumerator . Current )
124
+ ? _queryingEnumerable . _shaper ( _queryingEnumerable . _cosmosQueryContext , _enumerator . Current )
103
125
: default ;
104
126
105
127
return hasNext ;
106
128
}
107
129
}
108
130
catch ( Exception exception )
109
131
{
110
- _logger . QueryIterationFailed ( _contextType , exception ) ;
132
+ _queryingEnumerable . _logger . QueryIterationFailed ( _queryingEnumerable . _contextType , exception ) ;
111
133
112
134
throw ;
113
135
}
0 commit comments