2

I have an ASP.NET core application where I use a service layer between my controllers and Entity Framework.

Currently my services are synchronous, but I would like to make them asynchronous.

This is an controller example:

public async Task<IActionResult> Search(BusinessesSearchModel model)
{
    var resultModel = await _businessService.Search(model);
    return Ok(resultModel);
}

And this is an example of my service:

public interface IBusinessesService
{
     Task<BusinessResultListModel> Search(BusinessesSearchModel model);
}

public class BusinessesService : IBusinessesService
{
     public async Task<BusinessResultListModel> Search(BusinessesSearchModel model)
    {
        var queryResult = (from b in MyDBContext.Businesses

                            where b.Name.Contains(model.Name)
                            && b.Phone.Contains(model.Phone)

                            select new BusinessesListModel
                            {
                                ID = b.ID,
                                Name = b.Name,
                                Phone = b.Phone
                            }
                            ).ToList();
        var resultModel = new BusinessResultListModel();
        resultModel.data = queryResult;
        resultModel.othervalue = "other value";
        return resultModel;
    }
}

This does not work. Visual Studio tells me:

This async method lacks 'await' operators and will run synchronously

Where should I add await to make this async?

3
  • 2
    At var queryResult = "LINQ query here"... What have you tried? Commented Jan 18, 2017 at 12:43
  • Your question isn't clear here. What is your query result? Are you using Linq to Sql or Linq to objects? later one doesn't support async. linq to sql (i.e. using entity framework/IQueryable) can support it Commented Jan 18, 2017 at 12:43
  • Sorry about that. I have updated the query part. I'm using EF. Commented Jan 18, 2017 at 12:49

2 Answers 2

4

Your code isn't doing anyting asynchronously. To utilize the await/async API, you need to be invoking an async method inside your own method (unless you want to implement the async logic yourself).

In your case, if you're using Entity Framework, you can use it's async methods for querying:

public class BusinessesService : IBusinessesService
{
     public async Task<BusinessResultListModel> Search(BusinessesSearchModel model)
    {
        var queryResult = await _context.YourEntity.Where(x => x.SomeProperty == model.Query).ToListAsync(); //<--- This is your async call, awaiting the ToListAsync() method
        var resultModel = new BusinessResultListModel();
        resultModel.data = queryResult;
        resultModel.othervalue = "other value";
        return resultModel;
    }
}

Other async methods in EntityFramework are FirstOrDefaultAsync(), SingleOrDefaultAsync(), SaveChangesAsync() and so on

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you sir for explaining this to a humble noob!
1

you are missing the async within linq.

for example:

 public async Task<IEnumerable<SchedulerJob>> GetAllByIdsAsync(IEnumerable<int> ids, CancellationToken cancellationToken = default(CancellationToken))
    {
        return await Context.SchedulerJobs
            .Include(s => s.Program)
            .Where(job => ids.Contains(job.Id))
            .ToListAsync(cancellationToken);
    }

the ToListAsync(cancellationToken); in combination with await, and you are set to go!

i see you edited the page:

you need to do:

 public async Task<BusinessResultListModel> Search(BusinessesSearchModel model)
{
    //something like:
    var queryResult = await (from b in MyDBContext.Businesses

                        where b.Name.Contains(model.Name)
                        && b.Phone.Contains(model.Phone)

                        select new BusinessesListModel
                        {
                            ID = b.ID,
                            Name = b.Name,
                            Phone = b.Phone
                        }
                        ).ToListAsync();
    var resultModel = new BusinessResultListModel();
    resultModel.data = queryResult;
    resultModel.othervalue = "other value";
    return resultModel;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.