我们有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()
的值,也许吗?。
答案 0 :(得分:2)
FindAsync
在许多脚手架代码中,可以使用FindAsync代替 FirstOrDefaultAsync。
SingleOrDefaultAsync
获取更多数据并执行不必要的工作。如果抛出异常 有不止一个适合过滤器部分的实体。
FirstOrDefaultAsync
如果存在多个符合过滤条件的实体,则不会抛出 部分。