2020-02-13 10:35

EF Core 3.1 取得 IQueryable 的 SQL

private static T getPrivate<T>(this object obj, string privateField)
{
    return (T)obj?.GetType()
        .GetField(privateField, BindingFlags.Instance | BindingFlags.NonPublic)
        ?.GetValue(obj);
}

public static string ToSql<TEntity>(this IQueryable<TEntity> query) where TEntity : class
{
    var enumerator = query.Provider.Execute<IEnumerable<TEntity>>(query.Expression).GetEnumerator();

    var relationalQueryContext = enumerator.getPrivate<RelationalQueryContext>("_relationalQueryContext");
    var relationalCommandCache = enumerator.getPrivate<RelationalCommandCache>("_relationalCommandCache");

#pragma warning disable EF1001 // Internal EF Core API usage.
    IRelationalCommand command = relationalCommandCache.GetRelationalCommand(relationalQueryContext.ParameterValues);
#pragma warning restore EF1001 // Internal EF Core API usage.

    return command.CommandText;
}