Асинхронное программирование
Асинхронные операции не блокируют поток во время выполнения запроса в базе данных. Асинхронные операции важны для обеспечения адаптивного пользовательского интерфейса в расширенных клиентских приложениях, а также могут увеличить пропускную способность в веб-приложениях, где они освобождают поток для обслуживания других запросов в веб-приложениях.
После стандарта .NET EF Core предоставляет асинхронные аналоги для всех синхронных методов, выполняющих операции ввода-вывода. Они имеют те же эффекты, что и методы синхронизации, и могут использоваться с C# async
и await
ключевое слово. Например, вместо использования DbContext.SaveChanges, который блокирует поток во время выполнения операций ввода-вывода базы данных, можно использовать DbContext.SaveChangesAsync:
var blog = new Blog { Url = "http://sample.com" };
context.Blogs.Add(blog);
await context.SaveChangesAsync();
Дополнительные сведения см . в общих документах по асинхронном программировании C#.
Предупреждение
EF Core не поддерживает выполнение нескольких параллельных операций в одном экземпляре контекста. Следует подождать завершения одной операции, прежде чем запускать следующую. Для этого обычно нужно указать ключевое слово await
в каждой асинхронной операции.
Предупреждение
К сожалению, асинхронная реализация Microsoft.Data.SqlClient имеет некоторые известные проблемы (например , #593, #601 и другие). Если возникают непредвиденные проблемы с производительностью, попробуйте использовать выполнение команды синхронизации, особенно при работе с большим текстом или двоичными значениями.
Примечание.
EF Core передает маркеры отмены до используемого поставщика базовой базы данных (например, Microsoft.Data.SqlClient). Эти маркеры могут быть или не учитываются. Обратитесь к документации поставщика базы данных.
Асинхронные операторы LINQ
Для асинхронной поддержки выполнения запросов LINQ EF Core предоставляет набор асинхронных методов расширения, которые выполняют запрос и возвращают результаты. Эти аналоги стандартных синхронных операторов LINQ включают ToListAsync, SingleAsync, AsAsyncEnumerableи т. д.:
var blogs = await context.Blogs.Where(b => b.Rating > 3).ToListAsync();
Обратите внимание, что нет асинхронных версий некоторых операторов LINQ, таких как Where или OrderBy, так как они создают только дерево выражений LINQ и не вызывают выполнение запроса в базе данных. Только операторы, вызывающие выполнение запросов, имеют асинхронные аналоги.
Важно!
Асинхронные методы расширения EF Core определяются в пространстве имен Microsoft.EntityFrameworkCore
. Это пространство имен необходимо импортировать, чтобы методы стали доступными.
Операторы асинхронного асинхронного LINQ на стороне клиента
Описанные выше асинхронные операторы LINQ можно использовать только в запросах EF. Их нельзя использовать с клиентским запросом LINQ to Objects. Для выполнения асинхронных операций LINQ на стороне клиента за пределами EF используйте System.Linq.Async
пакет. Этот пакет может быть особенно полезен для выполнения операций с клиентом, которые не могут быть переведены для оценки на сервере.
В EF Core 6.0 и более низкой ссылки, к System.Linq.Async
сожалению, вызывает неоднозначные ошибки компиляции вызовов для операторов LINQ, применяемых к DbSets EF. Это затрудняет использование EF и System.Linq.Async
в одном проекте. Чтобы обойти эту проблему, добавьте AsQueryable в DbSet:
var groupedHighlyRatedBlogs = await context.Blogs
.AsQueryable()
.Where(b => b.Rating > 3) // server-evaluated
.AsAsyncEnumerable()
.GroupBy(b => b.Rating) // client-evaluated
.ToListAsync();