AspnetCore Odata Как создать асинхронное действие, вызывающее ожидающий запрос

Вот мой контроллер ODATA с действием ODATA.

   public class MyController : ODataController
{
    private readonly Repository_repo;

    public MyController(IRepository repo)
    {
        _repo = repo;
    }

    [EnableQuery(PageSize = 10, EnsureStableOrdering = false)]
    public IActionResult Get()
    {
        var data = _repo.GetData();
        return Ok(data)

    }

}

Вот мой метод репозитория.

   public IQueryable<DataModel> GetData() => _db.DbSet.Select(data=> new DataModel
    {
        // Implement model
    }).

Теперь я понимаю, что нет смысла делать метод GetData в репозитории асинхронным, потому что он просто возвращает запрос, который не выполняется, пока вы не вызовете его перечислитель.

Таким образом, асинхронная часть - это метод действия. Как бы я сделал этот асинхронный ожидаемый звонок? Насколько мне известно, метод Odata EnableQuery ожидает IQueryable.

2 ответа

Тебе не нужно. Метод действия - это только одна часть конвейера запросов; отсутствие асинхронности не препятствует асинхронности других объектов в конвейере. Промежуточное программное обеспечение, которое обрабатывает запрос OData, - это то, что фактически отправляет запрос в базу данных, и, скорее всего, делает это асинхронно (я не знаком с исходным кодом и не могу сказать однозначно). Независимо от того, ваше действие должно быть асинхронным, только если вы действительно делаете что-то асинхронное в нем. В противном случае, не беспокойтесь об этом.

заставьте свои репозитории реализовать IAsyncEnumerable, преобразовав IQueryable в AsyncEnumerator:

      public class RepositoryOfDataModel : IAsyncEnumerable<DataModel>
{
  ...
  public IAsyncEnumerator<DataModel> GetAsyncEnumerator(CancellationToken cancellationToken = default)
    => ((IAsyncEnumerable<DataModel>)this.GetData()).GetAsyncEnumerator(cancellationToken);
  ...
}

теперь вы сможете сделать свой контроллер асинхронным:

      public class MyController : ODataController
{
  private readonly Repository _repo;

  public MyController(IRepository repo)
  {
    _repo = repo;
  }

  [EnableQuery(PageSize = 10, EnsureStableOrdering = false)]
  public async Task<ActionResult<IEnumerable<DataModel>>> Get()
  {
    return await _repo.DataModels.ToListAsync();
  }
}
Другие вопросы по тегам