Spectre.Query is a library for doing simplified (safe) querying in Entity Framework Core. Perfect when you want to let end users or APIs search with a SQL-esque language without actually letting them execute any SQL directly (which you never should).
ID > 0 AND Year < 2007 AND Comment != null AND (!Seen OR Comment LIKE '%Awesome%')
This project is currently under active development and might not be ready for production.
PM> Install-Package Spectre.Query
var provider = QueryProviderBuilder.Build(context, options =>
{
options.Configure<Movie>(movie =>
{
movie.Map("Id", e => e.MovieId);
movie.Map("Genre", e => e.Genre.Name);
movie.Map("Title", e => e.Name);
movie.Map("Year", e => e.ReleasedAt);
movie.Map("Score", e => e.Rating);
movie.Map("Seen", e => e.Seen);
});
});
The created IQueryProvider<TContext>
is thread safe and
can be cached for the duration of the application.
var movies = provider.Query<Movie>(context, "NOT Seen AND Score > 60").ToList();
PM> Install-Package Spectre.Query.AspNetCore
Start by adding the registrations in your Startup.cs
.
public void ConfigureServices(IServiceCollection services)
{
services.AddQueryProvider<MovieDbContext>(options =>
{
options.Configure<Movie>(movie =>
{
movie.Map("Id", e => e.MovieId);
movie.Map("Genre", e => e.Genre.Name);
movie.Map("Title", e => e.Name);
movie.Map("Year", e => e.ReleasedAt);
movie.Map("Score", e => e.Rating);
movie.Map("Seen", e => e.Seen);
});
});
// ...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// This is not required, but will make sure that all
// initialization is performed at start up and not at
// the first time the query provider is used.
app.UseQueryProvider<MovieDbContext>();
// ...
}
[ApiController]
[Route("api/movies")]
public class MovieController : ControllerBase
{
private readonly MovieContext _context;
private readonly IQueryProvider<MovieContext> _provider;
public MovieController(MovieContext context, IQueryProvider<MovieContext> provider)
{
_context = context;
_provider = provider;
}
[HttpGet]
public IActionResult<List<Movie>> Query([FromHeader]string query = "Rating > 80 AND !Seen")
{
return _provider.Query<Movie>(_context, query)
.OrderByDescending(movie => movie.Rating)
.ToList()
}
}
Copyright © Spectre Systems
Spectre.Query is provided as-is under the MIT license. For more information see LICENSE.