Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entity Framework should support constructing queries outside the DbContext similar to NHibernate DetachedCritera #4563

Closed
jeffreyabecker opened this issue Feb 14, 2016 · 3 comments
Assignees

Comments

@jeffreyabecker
Copy link

This is a feature request

Entity Framework should support constructing IQueryable instances outside the DbContext and attaching for execution. Conceptually this is similar to NHibernate's DetachedCritera class. An api might look something like:

var q = DetachedQuery.Of<Student>().Where(s=>s.GPA > 3.0 && s.LastName.StartsWith("Q"));
...
var qStudentsWithGoodGrades = schoolDb.Search(q);

Why: This makes it easier to encapsulate and unit test potentially complicated query construction logic such as search forms. The relevant fields can be wrapped up into a class with a method or methods that construct the relevant detached query. Unit tests can then construct the class and inspect the result of the query construction. This is particularly useful in a WebApi scenario where the model class in the GET method can fully encapsulate the querying logic.

The implementation is fairly trivial. DetachedQuery.Of<TEntity>() returns an IQueryable with a dummy root ConstantExpression. Before execution schoolDb.Search<TEntity>() rewrites the expression tree replacing the dummy constants with EntityFramework DbSets or any other source of IQueryable instances.

Questions:

  • Is this something anyone would even want?
  • Is this something more appropriate for a different layer of the framework? Should the API for creating and rewriting DetatchedQueryables be defined elsewhere so that other projects can use this without depending on EntityFramework?
  • Is this better off as one or more separate nuget packages entirely? Technically this depends on only public API calls.
@divega
Copy link
Contributor

divega commented Feb 17, 2016

@jeffreyabecker This does sound to me like something that could be built to work independently of EF.

On the other hand as @anpete suggested earlier today it should be easy in C# to create a method (or lambda) that takes the IQueryable<T> root as an argument and then applies all the query operators to it. Once you have this you can choose to apply it to a dummy root (if the goal is just to inspect the tree) to an in-memory (i.e. LINQ to Objects) IQuerable<T> or to an EF DbSet<T>, e.g.:

public IQueryable<TResult> MyQuery<TSource, TResult>(IQueryable<TSource> sourceQuery)
{
   return sourceQuery.Where(s=>s.GPA > 3.0 && s.LastName.StartsWith("Q"));
}

Given how easy this is with LINQ (Hibernate/NHibernate probably had to come up with its own mechanism) I am not sure there is much value in the feature.

@ArieJones
Copy link

@divega There is actually a pretty similar type of implementation that is part of an Unit of Work and Repository Framework that is on CodePlex ( https://genericunitofworkandrepositories.codeplex.com ).
They can find examples under the samples code area that shows how it is implemented with some custom queries for the Northwind database.

It's basically the same type of process that you talk about above.

@divega
Copy link
Contributor

divega commented Feb 17, 2016

We discussed this again in triage and we agreed that we won't be adding this as a feature of EF Core. As explained before, the main reasons are:

  1. It is easy to factor application code in a way that a different alternative IQueryable<T> roots are used to construct the query using the same code.
  2. The scenario could also be addressed in an external library without depending on EF Core.

@divega divega closed this as completed Feb 17, 2016
@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants