Я только что узнал о QueryUnbufferedAsync и IAsyncEnumerable здесь https://www.learndapper.com/dapper-query/selecting-unbuffered-async
и хотел использовать его в своем собственном классе службы данных, но я делаю что-то не так, поскольку он не компилируется. Я думаю, что путаю типы возвращаемых данных, но не могу понять, как их использовать.
Вот мой код:
private async Task<T> GetAsync2<T>(Func<DbConnection, Task<T>> operation)
{
if (operation is null) { throw new ArgumentNullException(nameof(operation)); }
await using DbConnection myCon = new SnowflakeDbConnection("myConnectionString");
await myCon.OpenAsync();
var result = await databaseOperation(myCon);
return result;
}
public async Task<IAsyncEnumerable<T>> GetAllAsync<T>(string sqlSelect) => await GetAsync2(conn => conn.QueryUnbufferedAsync<T>(sqlSelect));
Это ошибка сборки, которую я получаю:
Аргументы типа для метода GetAsync2(Func<DbConnection, Task>) нельзя вывести из использования.





QueryUnbufferedAsync возвращает IAsyncEnumerable. Это не async Task<IAsyncEnumerable, потому что IAsyncEnumerable уже поддерживает асинхронность.
Итак, вам нужна еще одна перегрузка, которая принимает делегат, отличный от Task.
Однако из-за того, что оно не буферизовано, вы не можете закрыть соединение, пока данные не будут прочитаны. Поэтому вам нужно (и в любом случае следует) полагаться на Dapper для открытия и закрытия соединения после полного считывания данных. Dapper может справиться с этим, если соединение было закрыто, когда вы начали операцию.
private T GetFromDb<T>(Func<DbConnection, T> operation)
{
// do NOT add using
var myCon = new SnowflakeDbConnection("myConnectionString");
var result = operation(myCon);
return result;
}
public IAsyncEnumerable<T> GetAllAsync<T>(string sqlSelect) =>
GetFromDb(conn => conn.QueryUnbufferedAsync<T>(sqlSelect));
Однако на данный момент я не уверен, что вы получите, возясь с делегатами.
совершенно верно, у меня изначально было открытие соединения
Добрался, спасибо, воспользовался вашим предложением, но получил ошибку компиляции GetAllAsync, говорящую: «Невозможно вернуть значение из итератора. Используйте оператор возврата возврата, чтобы вернуть значение, или разрыв выхода, чтобы завершить итерацию».
Я изменил его на это ниже, теперь ошибка компиляции исчезла. Теперь пытаюсь выяснить, как на самом деле использовать его в потребительских методах. public async IAsyncEnumerable<T> GetAllAsync<T>(string sqlSelect) { yield return (T)GetFromDb(conn => conn.QueryUnbufferedAsync<T>(sqlSelect)); }
Нет, не делайте этого, используйте вместо этого мой код. Извините, у меня там был посторонний async.
Спасибо, сделаю. Я вернусь к этому позже, но отмечу ваше как ответ. Спасибо за помощь
Нет, не пропало. Делегат не возвращает
Task, посколькуQueryUnbufferedAsyncне возвращает.