.Net EF Core 2.1 Get DbContext from IQueryable argument
up vote
0
down vote
favorite
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();
entity-framework-core asp.net-core-2.0 dbcontext
add a comment |
up vote
0
down vote
favorite
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();
entity-framework-core asp.net-core-2.0 dbcontext
This won't work with just any IQueryable implementation so we have to rely on the underlying types. What is the value ofquery.GetType().FullNamefor the IQueryable you want to use this on?
– Daniel Rothig
Nov 7 at 22:22
For FullName of this Query type (<T> is 'Item') I'm getting: "Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[[EFCore.MyExtensions.Tests.Item, EFCore.MyExtensions.Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"
– borisdj
Nov 7 at 22:30
This is a really peculiar thing to want to do, perhaps you could explain why you need this?
– DavidG
Nov 7 at 22:33
For BatchDelete as Extension on Query.
– borisdj
Nov 7 at 22:35
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
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();
entity-framework-core asp.net-core-2.0 dbcontext
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();
entity-framework-core asp.net-core-2.0 dbcontext
entity-framework-core asp.net-core-2.0 dbcontext
edited Nov 7 at 23:05
asked Nov 7 at 21:49
borisdj
5911721
5911721
This won't work with just any IQueryable implementation so we have to rely on the underlying types. What is the value ofquery.GetType().FullNamefor the IQueryable you want to use this on?
– Daniel Rothig
Nov 7 at 22:22
For FullName of this Query type (<T> is 'Item') I'm getting: "Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[[EFCore.MyExtensions.Tests.Item, EFCore.MyExtensions.Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"
– borisdj
Nov 7 at 22:30
This is a really peculiar thing to want to do, perhaps you could explain why you need this?
– DavidG
Nov 7 at 22:33
For BatchDelete as Extension on Query.
– borisdj
Nov 7 at 22:35
add a comment |
This won't work with just any IQueryable implementation so we have to rely on the underlying types. What is the value ofquery.GetType().FullNamefor the IQueryable you want to use this on?
– Daniel Rothig
Nov 7 at 22:22
For FullName of this Query type (<T> is 'Item') I'm getting: "Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[[EFCore.MyExtensions.Tests.Item, EFCore.MyExtensions.Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"
– borisdj
Nov 7 at 22:30
This is a really peculiar thing to want to do, perhaps you could explain why you need this?
– DavidG
Nov 7 at 22:33
For BatchDelete as Extension on Query.
– borisdj
Nov 7 at 22:35
This won't work with just any IQueryable implementation so we have to rely on the underlying types. What is the value of
query.GetType().FullName for the IQueryable you want to use this on?– Daniel Rothig
Nov 7 at 22:22
This won't work with just any IQueryable implementation so we have to rely on the underlying types. What is the value of
query.GetType().FullName for the IQueryable you want to use this on?– Daniel Rothig
Nov 7 at 22:22
For FullName of this Query type (<T> is 'Item') I'm getting: "Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[[EFCore.MyExtensions.Tests.Item, EFCore.MyExtensions.Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"
– borisdj
Nov 7 at 22:30
For FullName of this Query type (<T> is 'Item') I'm getting: "Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[[EFCore.MyExtensions.Tests.Item, EFCore.MyExtensions.Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"
– borisdj
Nov 7 at 22:30
This is a really peculiar thing to want to do, perhaps you could explain why you need this?
– DavidG
Nov 7 at 22:33
This is a really peculiar thing to want to do, perhaps you could explain why you need this?
– DavidG
Nov 7 at 22:33
For BatchDelete as Extension on Query.
– borisdj
Nov 7 at 22:35
For BatchDelete as Extension on Query.
– borisdj
Nov 7 at 22:35
add a comment |
2 Answers
2
active
oldest
votes
up vote
1
down vote
Sounds like you want to implement ActiveRecord in Entity Framework. Many have tried... Best I can suggest is make your context.Items property something LINQ-like that bootlegs the context, e.g:
public class MyContext : DbContext
{
QueryableWithContext<Item> Items {get => new QueryableWithContext<Item>(ItemsSet, this)}
private DbSet<Item> ItemsSet {get;set;}
}
public class QueryableWithContext<T>
{
public DbContext Context { get; }
private IQueryable<T> inner;
public QueryableWithContext(IQueryable<T> inner, DbContext context)
{
this.inner = inner;
this.Context = context;
}
public QueryableWithContext<T> Where(Func<T,bool> predicate)
{
return new QueryableWithContext<T>(inner.Where(predicate) as IQueryable<T>, Context);
}
// plus lots of other LINQ-like expressions
}
Then your extension method is not on IQueryable<T> but on QueryableWithContext<T>, and can access the Context property.
Nice idea, but requires separate QueryableWithContext for each set, so not ideal. I just might stick with sending Context as argument.
– borisdj
Nov 8 at 7:18
Yep I'd recommend that
– Daniel Rothig
Nov 8 at 23:52
add a comment |
up vote
0
down vote
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;
stateManager = stateManager ?? (((LazyRef<IStateManager>)stateManagerProperty)?.Value ?? ((dynamic)stateManagerProperty).Value);
return stateManager.Context;
}
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
Sounds like you want to implement ActiveRecord in Entity Framework. Many have tried... Best I can suggest is make your context.Items property something LINQ-like that bootlegs the context, e.g:
public class MyContext : DbContext
{
QueryableWithContext<Item> Items {get => new QueryableWithContext<Item>(ItemsSet, this)}
private DbSet<Item> ItemsSet {get;set;}
}
public class QueryableWithContext<T>
{
public DbContext Context { get; }
private IQueryable<T> inner;
public QueryableWithContext(IQueryable<T> inner, DbContext context)
{
this.inner = inner;
this.Context = context;
}
public QueryableWithContext<T> Where(Func<T,bool> predicate)
{
return new QueryableWithContext<T>(inner.Where(predicate) as IQueryable<T>, Context);
}
// plus lots of other LINQ-like expressions
}
Then your extension method is not on IQueryable<T> but on QueryableWithContext<T>, and can access the Context property.
Nice idea, but requires separate QueryableWithContext for each set, so not ideal. I just might stick with sending Context as argument.
– borisdj
Nov 8 at 7:18
Yep I'd recommend that
– Daniel Rothig
Nov 8 at 23:52
add a comment |
up vote
1
down vote
Sounds like you want to implement ActiveRecord in Entity Framework. Many have tried... Best I can suggest is make your context.Items property something LINQ-like that bootlegs the context, e.g:
public class MyContext : DbContext
{
QueryableWithContext<Item> Items {get => new QueryableWithContext<Item>(ItemsSet, this)}
private DbSet<Item> ItemsSet {get;set;}
}
public class QueryableWithContext<T>
{
public DbContext Context { get; }
private IQueryable<T> inner;
public QueryableWithContext(IQueryable<T> inner, DbContext context)
{
this.inner = inner;
this.Context = context;
}
public QueryableWithContext<T> Where(Func<T,bool> predicate)
{
return new QueryableWithContext<T>(inner.Where(predicate) as IQueryable<T>, Context);
}
// plus lots of other LINQ-like expressions
}
Then your extension method is not on IQueryable<T> but on QueryableWithContext<T>, and can access the Context property.
Nice idea, but requires separate QueryableWithContext for each set, so not ideal. I just might stick with sending Context as argument.
– borisdj
Nov 8 at 7:18
Yep I'd recommend that
– Daniel Rothig
Nov 8 at 23:52
add a comment |
up vote
1
down vote
up vote
1
down vote
Sounds like you want to implement ActiveRecord in Entity Framework. Many have tried... Best I can suggest is make your context.Items property something LINQ-like that bootlegs the context, e.g:
public class MyContext : DbContext
{
QueryableWithContext<Item> Items {get => new QueryableWithContext<Item>(ItemsSet, this)}
private DbSet<Item> ItemsSet {get;set;}
}
public class QueryableWithContext<T>
{
public DbContext Context { get; }
private IQueryable<T> inner;
public QueryableWithContext(IQueryable<T> inner, DbContext context)
{
this.inner = inner;
this.Context = context;
}
public QueryableWithContext<T> Where(Func<T,bool> predicate)
{
return new QueryableWithContext<T>(inner.Where(predicate) as IQueryable<T>, Context);
}
// plus lots of other LINQ-like expressions
}
Then your extension method is not on IQueryable<T> but on QueryableWithContext<T>, and can access the Context property.
Sounds like you want to implement ActiveRecord in Entity Framework. Many have tried... Best I can suggest is make your context.Items property something LINQ-like that bootlegs the context, e.g:
public class MyContext : DbContext
{
QueryableWithContext<Item> Items {get => new QueryableWithContext<Item>(ItemsSet, this)}
private DbSet<Item> ItemsSet {get;set;}
}
public class QueryableWithContext<T>
{
public DbContext Context { get; }
private IQueryable<T> inner;
public QueryableWithContext(IQueryable<T> inner, DbContext context)
{
this.inner = inner;
this.Context = context;
}
public QueryableWithContext<T> Where(Func<T,bool> predicate)
{
return new QueryableWithContext<T>(inner.Where(predicate) as IQueryable<T>, Context);
}
// plus lots of other LINQ-like expressions
}
Then your extension method is not on IQueryable<T> but on QueryableWithContext<T>, and can access the Context property.
answered Nov 7 at 23:45
Daniel Rothig
5448
5448
Nice idea, but requires separate QueryableWithContext for each set, so not ideal. I just might stick with sending Context as argument.
– borisdj
Nov 8 at 7:18
Yep I'd recommend that
– Daniel Rothig
Nov 8 at 23:52
add a comment |
Nice idea, but requires separate QueryableWithContext for each set, so not ideal. I just might stick with sending Context as argument.
– borisdj
Nov 8 at 7:18
Yep I'd recommend that
– Daniel Rothig
Nov 8 at 23:52
Nice idea, but requires separate QueryableWithContext for each set, so not ideal. I just might stick with sending Context as argument.
– borisdj
Nov 8 at 7:18
Nice idea, but requires separate QueryableWithContext for each set, so not ideal. I just might stick with sending Context as argument.
– borisdj
Nov 8 at 7:18
Yep I'd recommend that
– Daniel Rothig
Nov 8 at 23:52
Yep I'd recommend that
– Daniel Rothig
Nov 8 at 23:52
add a comment |
up vote
0
down vote
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;
stateManager = stateManager ?? (((LazyRef<IStateManager>)stateManagerProperty)?.Value ?? ((dynamic)stateManagerProperty).Value);
return stateManager.Context;
}
add a comment |
up vote
0
down vote
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;
stateManager = stateManager ?? (((LazyRef<IStateManager>)stateManagerProperty)?.Value ?? ((dynamic)stateManagerProperty).Value);
return stateManager.Context;
}
add a comment |
up vote
0
down vote
up vote
0
down vote
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;
stateManager = stateManager ?? (((LazyRef<IStateManager>)stateManagerProperty)?.Value ?? ((dynamic)stateManagerProperty).Value);
return stateManager.Context;
}
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;
stateManager = stateManager ?? (((LazyRef<IStateManager>)stateManagerProperty)?.Value ?? ((dynamic)stateManagerProperty).Value);
return stateManager.Context;
}
answered Nov 16 at 15:13
borisdj
5911721
5911721
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53198376%2fnet-ef-core-2-1-get-dbcontext-from-iqueryable-argument%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
This won't work with just any IQueryable implementation so we have to rely on the underlying types. What is the value of
query.GetType().FullNamefor the IQueryable you want to use this on?– Daniel Rothig
Nov 7 at 22:22
For FullName of this Query type (<T> is 'Item') I'm getting: "Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[[EFCore.MyExtensions.Tests.Item, EFCore.MyExtensions.Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"
– borisdj
Nov 7 at 22:30
This is a really peculiar thing to want to do, perhaps you could explain why you need this?
– DavidG
Nov 7 at 22:33
For BatchDelete as Extension on Query.
– borisdj
Nov 7 at 22:35