Я пытаюсь абстрагировать EF Core с помощью репозитория и не могу понять, как сделать его асинхронным. Это синхронная версия:
public class UserRepository
{
private DbSet<User> users;
public UserRepository(ApplicationDbContext context)
{
users = context.Set<User>();
}
public IQueryable<User> GetAll()
{
return users;
}
...
}
Проблема в том, что для того, чтобы сделать запрос асинхронным, нам нужно использовать специальные методы расширения из EF, такие как ToListAsync()
или CountAsync()
, и если проект он использует репозиторий, ссылающийся на пространства имен EF, в чем смысл абстракции?
Еще одна вещь, которую я изучал, - возвращение IAsyncEnumerable<User>
, а затем использование этой официальной библиотеки для асинхронного использования LINQ. Однако я не смог заставить его работать должным образом, потому что при использовании этих новых методов LINQ запрос обрабатывается в. NET вместо преобразования синтаксиса LINQ в SQL. Давайте возьмем следующий запрос в качестве примера:
var result = await Repository.GetAll()
.Limit(10)
.ToListAsync();
При использовании методов расширения EF я видел этот запрос в SSMS:
exec sp_executesql N'SELECT [u].[Id], [u].[Deleted], [u].[EmailAddress], [u].[FirstName], [u].[LastName], [u].[PhoneNumber], [u].[Status], [u].[VerifiedEmailAddress], [u].[VerifiedPhoneNumber]
FROM [Users] AS [u]
ORDER BY (SELECT 1)
OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY',N'@__p_0 int,@__p_1 int',@__p_0=0,@__p_1=10
То есть из БД будет выбрано только 10 записей. , что я и хотел.
Но при использовании методов расширения System.Linq.Async
я все же получил тот же результат обратно в мой код C#, но этот запрос показывал в SSMS:
SELECT [u].[Id], [u].[Deleted], [u].[EmailAddress], [u].[FirstName], [u].[LastName], [u].[PhoneNumber], [u].[Status], [u].[VerifiedEmailAddress], [u].[VerifiedPhoneNumber]
FROM [Users] AS [u]
Нет ограничений вообще, то есть, если бы в таблице Users были миллионы строк, все они были бы выбраны каждый раз, когда я запускаю запрос, когда мне нужны только первые 10.
Есть ли способ работы с LINQ для SQL и asyn c потоков? Или, может быть, еще одна идея о том, как абстрагировать EF, но все же разрешать асинхронные c запросы?