Sto usando Entity Framework Core e ho bisogno di vedere quale codice SQL viene generato. Nelle versioni precedenti di Entity Framework avrei potuto utilizzare quanto segue:
string sql = ((System.Data.Objects.ObjectQuery)query).ToTraceString();
Dove query è un oggetto IQueryable ... Ma ToTraceString non è disponibile in EF Core.
Come posso fare qualcosa di simile in EF Core?
Questa risposta è per EF Core 2.1. Per EF Core 3.0 e 3.1 vedi la risposta di @Thom Kiesewetter
Poiché EF 7 viene rinominato in Entity Framework Core I ti riassumerò le opzioni per EF Core.
Esistono 3 approcci per la registrazione delle istruzioni SQL da IQueryable<>
:
Ecco il folle codice di riflessione (metodo di estensione):
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;
}
}
Dopo aver aggiunto questo metodo di estensione al codice, è possibile utilizzare il metodo come segue:
// Build a query using Entity Framework
var query = _context.Widgets.Where(w => w.IsReal && w.Id == 42);
// Get the generated SQL
var sql = query.ToSql();
Referral: http://rion.io/2016/10/19/accessing-entity-framework-core-queries-behind-the-scenes-in-asp-net-core/ e https://gist.github.com / rionmonster / 2c59f449e67edf8cd6164e9fe66c545a