Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.Net EF Core 2.1 Get DbContext from IQueryable argument

I have an IQueryable extension method:

public static void SomeExt<T>(this IQueryable<T> query, DbContext context) {...}

and I would like to know if there is some way to get DbContext from query so that DbContext argument could be removed leaving only:

public static void SomeExt<T>(this IQueryable<T> query) {...}

I have tried something like this Access DataContext behind IQueryable but its not working, getting zero fields.

Also there is way to get it from DbSet
Can you get the DbContext from a DbSet?
myDbSet.GetService<'ICurrentDbContext>().Context;
but that's not what I need. I want to get it from Query?

This is the query:
var q = context.Items.Where(a => a.StatusId = 1);

q.SomeExt(context);
vs
q.SomeExt();

like image 881
borisdj Avatar asked Jan 01 '23 15:01

borisdj


1 Answers

I have found a way to do this

public static DbContext GetDbContext(IQueryable query)
{
    var bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
    var queryCompiler = typeof(EntityQueryProvider).GetField("_queryCompiler", bindingFlags).GetValue(query.Provider);
    var queryContextFactory = queryCompiler.GetType().GetField("_queryContextFactory", bindingFlags).GetValue(queryCompiler);

    var dependencies = typeof(RelationalQueryContextFactory).GetProperty("Dependencies", bindingFlags).GetValue(queryContextFactory);
    var queryContextDependencies = typeof(DbContext).Assembly.GetType(typeof(QueryContextDependencies).FullName);
    var stateManagerProperty = queryContextDependencies.GetProperty("StateManager", bindingFlags | BindingFlags.Public).GetValue(dependencies);
    var stateManager = (IStateManager)stateManagerProperty;

    return stateManager.Context;
}

For EFCore 3 instead of

.GetProperty("Dependencies", bindingFlags)

use

.GetField("_dependencies", bindingFlags)
like image 194
borisdj Avatar answered Jan 04 '23 16:01

borisdj