0

If I use

// VERSION A
private static IResult Gets(AppDbContext db)
{
    var output = db.Courses.AsNoTracking().Select(c => new CourseDto { Id = c.Id, Credits = c.Credits });
    return Results.Ok(output);
}

instead of

// VERSION B
private static async Task<IResult> Gets(AppDbContext db)
{
    var output = db.Courses.AsNoTracking().Select(c => new CourseDto { Id = c.Id, Credits = c.Credits });
    return Results.Ok(await output.ToArrayAsync());
}

does the framework internally invoke one of ToArray(), ToArrayAsync(), ToList() or ToListAsync(), etc (among others) to "materialize" IQueryable<CourseDto> and produce JSON output?

One more question: Which approach should I choose? Version A or version B?

  • 2
    It's not going to be able to create JSON from an IQueryable without materializing the query results. So your first one is effectively `return Results.Ok(output.ToArray());` (or `ToList()`). It's at that point that your query is executed. If you explicitly use `.ToArrayAsync()`, then you are doing the query asynchronously and you get all the goodness that comes from async operations. Choosing the **B**lue pill here is the correct course of action – Flydog57 Sep 16 '22 at 16:51

2 Answers2

1

It's not going to be able to create JSON from an IQueryable without materializing the query results.

So your first one is effectively return Results.Ok(output.ToArray()); (or ToList()) (well, it's likely cheaper than either ToArray or ToList - it's really just the cost of foreaching through the data). It's at that point that your query is executed.

If you explicitly use .ToArrayAsync(), then you are doing the query asynchronously and you get all the goodness that comes from async operations. Choosing the Blue pill here is the correct course of action

If you don't make the async call explicitly, I'm pretty sure the query is going to be done synchronously. Without an async notation, the compiler can't build the scaffolding to support asynchronous operations. Remember, async requires async all the way down the stack

Flydog57
  • 6,851
  • 2
  • 17
  • 18
0

I'm no C# expert, but version B seems functionally the same as version A. await-ing an async method in this scenario accomplishes the same thing as just calling the synchronous method. I'd keep it simple & just use version A.

I don't believe this method will return JSON - just an IQueryable. I believe you can do:

private static IResult Gets(AppDbContext db)
{
    var output = db.Courses.AsNoTracking().Select(c => new CourseDto { Id = c.Id, Credits = c.Credits });
    return Json(output);
}

You may need to change the return type to ActionResult

Quasipickle
  • 4,383
  • 1
  • 31
  • 53
  • I am not sure whether the passed `output` of type `IQuerayble` will be materialized synchronously or asynchronously in `Results.Ok()`. It is one of aspects that I want to know. – The Real Masochist Sep 16 '22 at 16:01
  • 1
    I'm pretty sure the query is going to be done synchronously. Without an `async` notation, the compiler can't build the scaffolding to support asynchronous operations. Remember, `async` requires `async` all the way down the stack – Flydog57 Sep 16 '22 at 16:53