FirstOrDefaultAsync()和SingleOrDefaultAsync()与FindAsync()EFCore

时间:2019-02-22 03:37:42

标签: c# linq ef-core-2.0

我们有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文档所说的:

  

异步找到具有给定主键值的实体。如果   具有给定主键值的实体存在于上下文中,   然后立即将其返回,而无需向商店提出要求。   否则,将向商店请求具有给定实体的实体   主键值,并且该实体(如果找到)将附加到   上下文并返回。如果在上下文中找不到实体,或者   存储,然后返回null。

所以我的问题是,如果我们用于FirstOrDefault()SingleOrDefault()FindAsync()的给定条件是主键,我们有什么实际区别吗?

我认为第一次使用它们总是会打入数据库,但是下次调用会怎样?。也许EFCore可以使用与FirstOrDefault()相同的上下文来获取SingleOrDefault()FindAsync()的值,也许吗?

1 个答案:

答案 0 :(得分:2)

FindAsync

  

在许多脚手架代码中,可以使用FindAsync代替   FirstOrDefaultAsync。

SingleOrDefaultAsync

  

获取更多数据并执行不必要的工作。如果抛出异常   有不止一个适合过滤器部分的实体。

FirstOrDefaultAsync

  

如果存在多个符合过滤条件的实体,则不会抛出   部分。

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