Skip to content

Commit e78bd02

Browse files
author
zzzprojects
committed
Fix EF Core Preview
Fix EF Core Preview
1 parent 2c9de52 commit e78bd02

File tree

2 files changed

+123
-23
lines changed

2 files changed

+123
-23
lines changed

src/shared/Z.EF.Plus.QueryFuture.Shared/BaseQueryFuture.cs

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public virtual void ExecuteInMemory()
8282
public virtual IRelationalCommand CreateExecutorAndGetCommand(out RelationalQueryContext queryContext)
8383
{
8484
bool isEFCore2x = false;
85+
bool EFCore_2_1 = false;
8586

8687
var context = Query.GetDbContext();
8788

@@ -102,13 +103,38 @@ public virtual IRelationalCommand CreateExecutorAndGetCommand(out RelationalQuer
102103
var queryCompiler = queryCompilerField.GetValue(Query.Provider);
103104

104105
// REFLECTION: Query.Provider.NodeTypeProvider (Use property for nullable logic)
105-
var nodeTypeProviderField = queryCompiler.GetType().GetProperty("NodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance);
106-
var nodeTypeProvider = nodeTypeProviderField.GetValue(queryCompiler);
106+
var nodeTypeProviderProperty = queryCompiler.GetType().GetProperty("NodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance);
107+
object nodeTypeProvider;
108+
object QueryModelGenerator = null;
109+
110+
if (nodeTypeProviderProperty == null)
111+
{
112+
EFCore_2_1 = true;
113+
114+
var QueryModelGeneratorField = queryCompiler.GetType().GetField("_queryModelGenerator", BindingFlags.NonPublic | BindingFlags.Instance);
115+
QueryModelGenerator = QueryModelGeneratorField.GetValue(queryCompiler);
116+
117+
var nodeTypeProviderField = QueryModelGenerator.GetType().GetField("_nodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance);
118+
nodeTypeProvider = nodeTypeProviderField.GetValue(QueryModelGenerator);
119+
}
120+
else
121+
{
122+
nodeTypeProvider = nodeTypeProviderProperty.GetValue(queryCompiler);
123+
}
107124

108125
// REFLECTION: Query.Provider._queryCompiler.CreateQueryParser();
109126
#if NETSTANDARD2_0
110-
var createQueryParserMethod = queryCompiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Instance);
111-
var createQueryParser = (QueryParser)createQueryParserMethod.Invoke(queryCompiler, new[] { nodeTypeProvider });
127+
QueryParser createQueryParser = null;
128+
if (EFCore_2_1)
129+
{
130+
var queryParserMethod = QueryModelGenerator.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Instance);
131+
createQueryParser = (QueryParser)queryParserMethod.Invoke(QueryModelGenerator, new[] { nodeTypeProvider });
132+
}
133+
else
134+
{
135+
var queryParserMethod = queryCompiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Instance);
136+
createQueryParser = (QueryParser)queryParserMethod.Invoke(queryCompiler, new[] { nodeTypeProvider });
137+
}
112138
#else
113139
var createQueryParserMethod = queryCompiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Static);
114140
var createQueryParser = (QueryParser)createQueryParserMethod.Invoke(null, new[] { nodeTypeProvider });
@@ -120,7 +146,16 @@ public virtual IRelationalCommand CreateExecutorAndGetCommand(out RelationalQuer
120146

121147
// REFLECTION: Query.Provider._queryCompiler._evaluatableExpressionFilter
122148
#if NETSTANDARD2_0
123-
var evaluatableExpressionFilter = (IEvaluatableExpressionFilter)queryCompiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(queryCompiler);
149+
IEvaluatableExpressionFilter evaluatableExpressionFilter = null;
150+
151+
if (EFCore_2_1)
152+
{
153+
evaluatableExpressionFilter = (IEvaluatableExpressionFilter)QueryModelGenerator.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(QueryModelGenerator);
154+
}
155+
else
156+
{
157+
evaluatableExpressionFilter = (IEvaluatableExpressionFilter)queryCompiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(queryCompiler);
158+
}
124159
#else
125160
var evaluatableExpressionFilterField = queryCompiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Static);
126161
var evaluatableExpressionFilter = (IEvaluatableExpressionFilter) evaluatableExpressionFilterField.GetValue(null);
@@ -226,17 +261,31 @@ public virtual IRelationalCommand CreateExecutorAndGetCommand(out RelationalQuer
226261
}
227262

228263

229-
230264
Expression newQuery;
231265

266+
232267
if(isEFCore2x)
233268
{
234-
var parameterExtractingExpressionVisitorConstructor = typeof(ParameterExtractingExpressionVisitor).GetConstructors().First(x => x.GetParameters().Length == 5);
269+
var parameterExtractingExpressionVisitorConstructors = typeof(ParameterExtractingExpressionVisitor).GetConstructors();
235270

236-
var parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] {evaluatableExpressionFilter, queryContext, logger, true, false } );
237-
238-
// CREATE new query from query visitor
239-
newQuery = parameterExtractingExpressionVisitor.ExtractParameters(Query.Expression);
271+
if (parameterExtractingExpressionVisitorConstructors.Any(x => x.GetParameters().Length == 5))
272+
{
273+
// EF Core 2.1
274+
var parameterExtractingExpressionVisitorConstructor = parameterExtractingExpressionVisitorConstructors.First(x => x.GetParameters().Length == 5);
275+
var parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, logger, true, false });
276+
277+
// CREATE new query from query visitor
278+
newQuery = parameterExtractingExpressionVisitor.ExtractParameters(Query.Expression);
279+
}
280+
else
281+
{
282+
// EF Core 2.1 Preview 2. We pass null for the DbContext, may require something else!
283+
var parameterExtractingExpressionVisitorConstructor = parameterExtractingExpressionVisitorConstructors.First(x => x.GetParameters().Length == 6);
284+
var parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, logger, null, true, false });
285+
286+
// CREATE new query from query visitor
287+
newQuery = parameterExtractingExpressionVisitor.ExtractParameters(Query.Expression);
288+
}
240289
}
241290
else
242291
{

src/shared/Z.EF.Plus._Core.Shared/EFCore/IQueryable`/CreateCommand.cs

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,31 @@ public static IRelationalCommand CreateCommand<T>(this IQueryable<T> source, out
116116

117117
public static IRelationalCommand CreateCommand(this IQueryable source, out RelationalQueryContext queryContext)
118118
{
119+
bool EFCore_2_1 = false;
120+
119121
var compilerField = typeof(EntityQueryProvider).GetField("_queryCompiler", BindingFlags.NonPublic | BindingFlags.Instance);
120122
var compiler = compilerField.GetValue(source.Provider);
121123

122124
// REFLECTION: Query.Provider.NodeTypeProvider (Use property for nullable logic)
123-
var nodeTypeProviderField = compiler.GetType().GetProperty("NodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance);
124-
var nodeTypeProvider = nodeTypeProviderField.GetValue(compiler);
125+
var nodeTypeProviderProperty = compiler.GetType().GetProperty("NodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance);
126+
127+
object nodeTypeProvider;
128+
object QueryModelGenerator = null;
129+
130+
if (nodeTypeProviderProperty == null)
131+
{
132+
EFCore_2_1 = true;
133+
134+
var QueryModelGeneratorField = compiler.GetType().GetField("_queryModelGenerator", BindingFlags.NonPublic | BindingFlags.Instance);
135+
QueryModelGenerator = QueryModelGeneratorField.GetValue(compiler);
136+
137+
var nodeTypeProviderField = QueryModelGenerator.GetType().GetField("_nodeTypeProvider", BindingFlags.NonPublic | BindingFlags.Instance);
138+
nodeTypeProvider = nodeTypeProviderField.GetValue(QueryModelGenerator);
139+
}
140+
else
141+
{
142+
nodeTypeProvider = nodeTypeProviderProperty.GetValue(compiler);
143+
}
125144

126145
var queryContextFactoryField = compiler.GetType().GetField("_queryContextFactory", BindingFlags.NonPublic | BindingFlags.Instance);
127146
var queryContextFactory = (IQueryContextFactory)queryContextFactoryField.GetValue(compiler);
@@ -137,7 +156,16 @@ public static IRelationalCommand CreateCommand(this IQueryable source, out Relat
137156

138157
// REFLECTION: Query.Provider._queryCompiler._evaluatableExpressionFilter
139158
#if NETSTANDARD2_0
140-
var evaluatableExpressionFilter = (IEvaluatableExpressionFilter)compiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(queryCompiler);
159+
IEvaluatableExpressionFilter evaluatableExpressionFilter = null;
160+
161+
if (EFCore_2_1)
162+
{
163+
evaluatableExpressionFilter = (IEvaluatableExpressionFilter)QueryModelGenerator.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(QueryModelGenerator);
164+
}
165+
else
166+
{
167+
evaluatableExpressionFilter = (IEvaluatableExpressionFilter)compiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(queryCompiler);
168+
}
141169
#else
142170
var evalutableExpressionFilterField = compiler.GetType().GetField("_evaluatableExpressionFilter", BindingFlags.NonPublic | BindingFlags.Static);
143171
var evalutableExpressionFilter = (IEvaluatableExpressionFilter)evalutableExpressionFilterField.GetValue(null);
@@ -167,12 +195,26 @@ public static IRelationalCommand CreateCommand(this IQueryable source, out Relat
167195
.GetProperty("Logger", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
168196
var logger = loggerField.GetValue(dependencies2);
169197

170-
var parameterExtractingExpressionVisitorConstructor = typeof(ParameterExtractingExpressionVisitor).GetConstructors().First(x => x.GetParameters().Length == 5);
171-
172-
var parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] {evaluatableExpressionFilter, queryContext, logger, true, false} );
173-
174-
// CREATE new query from query visitor
175-
newQuery = parameterExtractingExpressionVisitor.ExtractParameters(source.Expression);
198+
var parameterExtractingExpressionVisitorConstructors = typeof(ParameterExtractingExpressionVisitor).GetConstructors();
199+
200+
if (parameterExtractingExpressionVisitorConstructors.Any(x => x.GetParameters().Length == 5))
201+
{
202+
// EF Core 2.1
203+
var parameterExtractingExpressionVisitorConstructor = parameterExtractingExpressionVisitorConstructors.First(x => x.GetParameters().Length == 5);
204+
var parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, logger, true, false });
205+
206+
// CREATE new query from query visitor
207+
newQuery = parameterExtractingExpressionVisitor.ExtractParameters(source.Expression);
208+
}
209+
else
210+
{
211+
// EF Core 2.1 Preview 2. We pass null for the DbContext, may require something else!
212+
var parameterExtractingExpressionVisitorConstructor = parameterExtractingExpressionVisitorConstructors.First(x => x.GetParameters().Length == 6);
213+
var parameterExtractingExpressionVisitor = (ParameterExtractingExpressionVisitor)parameterExtractingExpressionVisitorConstructor.Invoke(new object[] { evaluatableExpressionFilter, queryContext, logger, null, true, false });
214+
215+
// CREATE new query from query visitor
216+
newQuery = parameterExtractingExpressionVisitor.ExtractParameters(source.Expression);
217+
}
176218
}
177219
else
178220
{
@@ -193,9 +235,18 @@ public static IRelationalCommand CreateCommand(this IQueryable source, out Relat
193235
//var query = new QueryAnnotatingExpressionVisitor().Visit(source.Expression);
194236
//var newQuery = ParameterExtractingExpressionVisitor.ExtractParameters(query, queryContext, evalutableExpressionFilter);
195237

196-
#if NETSTANDARD2_0
197-
var queryParserMethod = compiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Instance);
198-
var queryparser = (QueryParser)queryParserMethod.Invoke(compiler, new[] { nodeTypeProvider });
238+
#if NETSTANDARD2_0
239+
QueryParser queryparser = null;
240+
if (EFCore_2_1)
241+
{
242+
var queryParserMethod = QueryModelGenerator.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Instance);
243+
queryparser = (QueryParser)queryParserMethod.Invoke(QueryModelGenerator, new[] { nodeTypeProvider });
244+
}
245+
else
246+
{
247+
var queryParserMethod = compiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Instance);
248+
queryparser = (QueryParser)queryParserMethod.Invoke(compiler, new[] { nodeTypeProvider });
249+
}
199250
#else
200251
var queryParserMethod = compiler.GetType().GetMethod("CreateQueryParser", BindingFlags.NonPublic | BindingFlags.Static);
201252
var queryparser = (QueryParser)queryParserMethod.Invoke(null, new[] { nodeTypeProvider });

0 commit comments

Comments
 (0)