3

This is the method inside the repository:

public async Task<IEnumerable<T>> FindAll()
    {
        IQueryable<T> query = this.Context.Set<T>();
        return await query.Select(e => e).ToListAsync();
    }


public class Program
{
    static void Main(string[] args)
    {
        DB dB = new DB();
        IUnitOfWork unitOfWork = new UnitOfWork(dB);
        Task<IEnumerable<User>> users = unitOfWork.UserRepository.FindAll();
        users.Wait();
        Console.WriteLine(users);
    }
}

When I run my code I am getting:

System.Runtime.CompilerServices.AsyncTaskMethodBuilder'1+AsyncStateMachineBox'1[System.Collections.Generic.IEnumerable'1[PasteBook.WebApi.Models.User],PasteBook.WebApi.Repositories.GenericRepository'1+d__5[PasteBook.WebApi.Models.User]]

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Dale
  • 49
  • 2
  • 1
    Look into [async Main](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-7.1/async-main), and then you can `await` the `FindAll` method call. – Lasse V. Karlsen May 09 '22 at 13:44
  • Your "unit-of-work" isn't working. Are you using the "repository" antipattern because it's supposed to be a Best Practice? Is `UnitOfWork` jsut a wrapper over a DbContext, which does the actual UoW work? – Panagiotis Kanavos May 09 '22 at 13:45
  • Does this answer your question? [Can't specify the 'async' modifier on the 'Main' method of a console app](https://stackoverflow.com/questions/9208921/cant-specify-the-async-modifier-on-the-main-method-of-a-console-app) – Liam May 09 '22 at 13:47
  • BTW that `FindAll` is loading all results in memory for no reason. Simply iterating over the `IQueryable` will execute the query but return one object at a time. This way iteration can start before all objects are loaded. If you have a lot of results this can save a lot of time and RAM – Panagiotis Kanavos May 09 '22 at 13:50
  • Finally, this `FindAll` loads the entire object even when you only need to use one or two properties. EF Core/LINQ on the other hand would generate queries that only retrieve the fields involved in the query. `_context.Users.Select(u=>u.Id)` produces `SELECT ID From users` instead of `SELECT * from Users`. – Panagiotis Kanavos May 09 '22 at 13:52

1 Answers1

4

The simplest option is just to use an async entry point:

public class Program
{
    // async Main method, with a Task return type
    static async Task Main(string[] args)
    {
        DB dB = new DB();
        IUnitOfWork unitOfWork = new UnitOfWork(dB);
        // It's fine to await within the async method
        var users = await unitOfWork.UserRepository.FindAll();
        foreach (var user in users)
        {
            Console.WriteLine(user);
        }
    }
}

(Note that this answer doesn't try to address whether you should be using this particular database access pattern - it's focused on "how to use await from a console app.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194