Proper approach for async call to database

Viewed 69

So im asking this question because I'm not sure which one of these options is the proper solution for staying async. I guess both will do the job, but still I want to be sure which one is the prefarable way:

Invoking method (stays the same)

  public async Task GetEntry(int id)
  {
     var entity = await _repository.GetByIdAsync(id)
  }

Option 1 : Repository Note: This option is not using the async modifier

  public Task<MyEntity> GetByIdAsync(int id)
  {
       return Query().SingleOrDefaultAsync(e => e.Id == id);
  }

  public IQueryable<MyEntity> Query()
  {
      return _dbContext.Set<MyEntity>().AsQueryable();;
  }

Option 2 : Repository (using await and the async modifier)

  public async Task<MyEntity> GetByIdAsync(int id)
  {
       return await Query().SingleOrDefaultAsync(e => e.Id == id);
  }

  public IQueryable<MyEntity> Query()
  {
      return _dbContext.Set<MyEntity>().AsQueryable();;
  }
1 Answers

I reckon this will be closed as opinion based, so I'll give my opinion first:

2 & 3 appear to be using EF unconventionally (e.g. not using the DbSet in the context directly, but by type).

1 isn't using EF at all, but can be useful for unit testing as the actual database call is hidden away (although you can use an in-memory database for testing EF if you are using .net core, so this might be moot anyway).

You could argue that the first function in 2 is good because it's just returning a task without awaiting (which saves a context switch).

One other thing to consider, is that even though EF supports async/await, each DbContext cannot be used by multiple tasks at the same time. You should get an exception if you try this. Of course, if each unit-of-work has a separate DbContext then that isn't an issue.

Related