.Net EF Core 2.1 从 IQueryable 参数获取 DbContext

bor*_*sdj 4 dbcontext entity-framework-core asp.net-core-2.0

我有一个 IQueryable 扩展方法:

public static void SomeExt<T>(this IQueryable<T> query, DbContext context) {...}
Run Code Online (Sandbox Code Playgroud)

我想知道是否有某种方法可以从查询中获取 DbContext,以便可以删除 DbContext 参数,只留下:

public static void SomeExt<T>(this IQueryable<T> query) {...}
Run Code Online (Sandbox Code Playgroud)

我在 IQueryable 后面尝试过类似Access DataContext 的东西, 但它不起作用,得到零字段。

也有办法从 DbSet 获取它
你能从 DbSet 获取 DbContext 吗?
myDbSet.GetService<'ICurrentDbContext>().Context;
但这不是我需要的。我想从 Query 中获取它?

这是查询:
var q = context.Items.Where(a => a.StatusId = 1);

q.SomeExt(上下文);
与
q.SomeExt();

bor*_*sdj 5

我找到了一种方法来做到这一点

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;
}
Run Code Online (Sandbox Code Playgroud)

对于 EFCore 3 而不是

.GetProperty("Dependencies", bindingFlags)
Run Code Online (Sandbox Code Playgroud)

用

.GetField("_dependencies", bindingFlags)
Run Code Online (Sandbox Code Playgroud)

  • 当心!虽然这有效,但它依赖于可能会在每次 EFCore 更新时更改的内部私有属性。即使是补丁版本也可能会破坏这一点。 (3认同)