-
-
Save nour-s/3bbf9b2588faa6b849393639a8b39757 to your computer and use it in GitHub Desktop.
Resolve the SQL being executed behind the scenes in Entity Framework Core
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Reflection; | |
using Microsoft.EntityFrameworkCore; | |
using Microsoft.EntityFrameworkCore.Query; | |
using Microsoft.EntityFrameworkCore.Query.Internal; | |
using Microsoft.EntityFrameworkCore.Storage; | |
public static class IQueryableExtensions | |
{ | |
private static readonly TypeInfo QueryCompilerTypeInfo = typeof(QueryCompiler).GetTypeInfo(); | |
private static readonly FieldInfo QueryCompilerField = typeof(EntityQueryProvider).GetTypeInfo().DeclaredFields.First(x => x.Name == "_queryCompiler"); | |
private static readonly FieldInfo QueryModelGeneratorField = QueryCompilerTypeInfo.DeclaredFields.First(x => x.Name == "_queryModelGenerator"); | |
private static readonly FieldInfo DataBaseField = QueryCompilerTypeInfo.DeclaredFields.Single(x => x.Name == "_database"); | |
private static readonly PropertyInfo DatabaseDependenciesField = typeof(Database).GetTypeInfo().DeclaredProperties.Single(x => x.Name == "Dependencies"); | |
public static string ToSql<TEntity>(this IQueryable<TEntity> query) where TEntity : class | |
{ | |
var queryCompiler = (QueryCompiler) QueryCompilerField.GetValue(query.Provider); | |
var modelGenerator = (QueryModelGenerator) QueryModelGeneratorField.GetValue(queryCompiler); | |
var queryModel = modelGenerator.ParseQuery(query.Expression); | |
var database = (IDatabase) DataBaseField.GetValue(queryCompiler); | |
var databaseDependencies = (DatabaseDependencies) DatabaseDependenciesField.GetValue(database); | |
var queryCompilationContext = databaseDependencies.QueryCompilationContextFactory.Create(false); | |
var modelVisitor = (RelationalQueryModelVisitor) queryCompilationContext.CreateQueryModelVisitor(); | |
modelVisitor.CreateQueryExecutor<TEntity>(queryModel); | |
var sql = modelVisitor.Queries.First().ToString(); | |
return sql; | |
} | |
} |
Anyone knows how to port this to .net core 3? QueryModelGenerator
, RelationalQueryModelVisitor
and queryCompilationContext.CreateQuerymodelVisitor()
all seems to have vanished.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think where TEntity : class is not needed. If we remove that, the method will work when a select is mapped to non reference type. eg:
MyDatabaseContext.MyTable.Select(t => t.Id).ToSql();
otherwise above will not compile.