Skip to content
This repository has been archived by the owner on Jun 9, 2021. It is now read-only.

A simple query language for Entity Framework Core.

License

Notifications You must be signed in to change notification settings

spectresystems/spectre.query

Repository files navigation

Spectre.Query

NuGet Build Status

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.

Table of Contents

  1. Usage
  2. Usage (ASP.NET Core)
  3. License

Usage

1. Install the NuGet package

PM> Install-Package Spectre.Query

2. Create the query provider

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.

3. Query the database

var movies = provider.Query<Movie>(context, "NOT Seen AND Score > 60").ToList();

Usage (ASP.NET Core)

1. Install the NuGet package

PM> Install-Package Spectre.Query.AspNetCore

2. Register the query provider

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>();

    // ...
}

3. Query the database

[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()
    }
}

License

Copyright © Spectre Systems

Spectre.Query is provided as-is under the MIT license. For more information see LICENSE.