Home > OS >  How to query on SQL Server in .NET 6 minimal API by anything other than Id
How to query on SQL Server in .NET 6 minimal API by anything other than Id

Time:11-29

I have a small database that has been created by EF using a typical model class:

public class Metrics
{
    public int Id { get; set; }
    public string? MetricValue { get; set; }
    public string? MetricHost { get; set; }
    public string? MetricTime { get; set; }
}

The database is now populated with data and my Minimal API can return all the entries from:

app.MapGet("/metric", async (DataContext context) => await context.Metrics.ToListAsync());

And also, I can query by Id:

app.MapGet("/metric/{id}", async (DataContext context, int id) => 
    await context.Metrics.FindAsync(id) is Metric metric ? 
    Results.Ok(metric) :
    Results.NotFound("Metric not found"));

I've been searching the web for something that would show how to search by another property but have not found anything that works. e.g.,

app.MapGet("/hostnames/{MetricHost}"...

This article on CodeMaze is the closest I've found but none of the examples seem to work:

https://code-maze.com/aspnetcore-query-string-parameters-minimal-apis/

Any help is appreciated. Here's an example that did not work:

app.MapGet("/search", (SearchCriteria criteria) =>
{
    return $"Host: {criteria.MetricHost}, Id: {criteria.Id}";
});

With model changes:

public class Metric
{
    public int Id { get; set; }
    public string? MetricValue { get; set; }
    public string? MetricHost { get; set; }
    public string? MetricTime { get; set; }

    public static ValueTask<Metric?> BindAsync(HttpContext context, ParameterInfo parameter)
    {
        string hostname = context.Request.Query["MetricHost"];
        int.TryParse(context.Request.Query["Id"], out var id);

        var result = new Metric
        {
            MetricHost = hostname,
            Id = id
        };

        return ValueTask.FromResult<Metric?>(result);
    }
}

CodePudding user response:

You are binding wrong type, BindAsync should be part of SearchCriteria:

app.MapGet("/search", (SearchCriteria criteria, DataContext context) =>
{
    IQueryable<Metric> query = context.Metrics;
    if(criteria.MetricHost is not null)
    {
        query = query.Where(m => m.MetricHost == criteria.MetricHost)
    }
    // ... rest of filters
    return await query.ToListAsync();
});
public class SearchCriteria
{
    public string? MetricHost { get; set; }
    // ... rest of filters

    public static ValueTask<SearchCriteria?> BindAsync(HttpContext context, ParameterInfo parameter)
    {
        string hostname = context.Request.Query["MetricHost"];
        // ... rest of filters
        var result = new SearchCriteria
        {
            MetricHost = hostname,
        };
        return ValueTask.FromResult<SearchCriteria?>(result);
    }
}

Read more:

  • Related