FirstOrDefaultAsync () и SingleOrDefaultAsync () против FindAsync () EFCore - PullRequest
0 голосов
/ 22 февраля 2019

У нас есть 3 различных подхода, чтобы получить отдельные элементы из EFCore, они FirstOrDefaultAsync(), SingleOrDefaultAsync() (включая его версии с не возвращаемым значением по умолчанию, также у нас есть FindAsync() и, возможно, больше с той же целью, как LastOrDefaultAsync().

     var findItem = await dbContext.TodoItems
       .FindAsync(request.Id)
       .ConfigureAwait(false);

     var firstItem = await dbContext.TodoItems
        .FirstOrDefaultAsync(i => i.Id == request.Id)
        .ConfigureAwait(false);

     var singleItem = await dbContext.TodoItems
        .SingleOrDefaultAsync(i => i.Id == request.Id)
        .ConfigureAwait(false);

Я хотел бы знать различия между каждым из них. До сих пор я знаю, что мы FirstOrDefaultAsync() получаем первое заданное условие (обычно используем это, потому что мы знаем, чтоболее чем один элемент может удовлетворять условию), с другой стороны, мы используем SingleOrDefaultAsync(), потому что мы знаем, что можно найти только одно возможное совпадение, и FindAsync(), чтобы получить элемент по его первичному ключу.

Я думаю, что FirstOrDefaultAsync() & SingleOrDefaultAsync() всегда попадает в базу данных (не уверен насчет этого), и FindAsync() это то, что говорит документация Microsoft:

Асинхронно находит объект с заданным первичным ключомзначения. Если сущность с заданными значениями первичного ключа существует в контексте, то она сразу возвращается без запроса в хранилище, в противном случае запрос делаетсяруда для сущности с заданными значениями первичного ключа, и эта сущность, если найдена, присоединяется к контексту и возвращается.Если никакая сущность не найдена в контексте или хранилище, возвращается нуль.

Поэтому мой вопрос заключается в том, является ли данное условие, используемое для FirstOrDefault(), SingleOrDefault() и FindAsync(),первичный ключ, есть ли у нас какая-либо фактическая разница?

Я думаю, что при первом использовании они всегда попадают в БД, , но как насчет следующих вызовов? .И, вероятно, EFCore мог бы использовать тот же контекст, чтобы получить значения для FirstOrDefault() и SingleOrDefault(), как и для FindAsync(), , может быть? .

1 Ответ

0 голосов
/ 22 февраля 2019

FindAsync

В большинстве кода скаффолдинга FindAsync может использоваться вместо FirstOrDefaultAsync.

SingleOrDefaultAsync

выбирает большеданные и делает ненужную работу.выдает исключение, если существует более одного объекта, который соответствует части фильтра.

FirstOrDefaultAsync

не выбрасывает, если существует более одного объекта, который соответствует части фильтра.

https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/crud?view=aspnetcore-2.2#singleordefaultasync-vs-firstordefaultasync

...