FirstOrDefaultAsync() & SingleOrDefaultAsync() 与 FindAsync() EFCore
FirstOrDefaultAsync() & SingleOrDefaultAsync() vs FindAsync() EFCore
我们有 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 文档是这样说的:
Asynchronously finds an entity with the given primary key values. If
an entity with the given primary key values exists in the context,
then it is returned immediately without making a request to the store.
Otherwise, a request is made to the store for an entity with the given
primary key values and this entity, if found, is attached to the
context and returned. If no entity is found in the context or the
store, then null is returned.
所以我的问题是,如果我们给定的用于 FirstOrDefault()
、SingleOrDefault()
和 FindAsync()
的条件是主键,我们有什么实际区别吗?
我的想法是,第一次使用它们总是命中数据库,但是下一次调用呢?。并且可能 EFCore 可以使用相同的上下文来获取 FirstOrDefault()
和 SingleOrDefault()
的值,就像它为 FindAsync()
、maybe?.[=28 所做的那样=]
查找异步
In much of the scaffolded code, FindAsync can be used in place of
FirstOrDefaultAsync.
SingleOrDefaultAsync
fetches more data and does unnecessary work. throws an exception if
there's more than one entity that fits the filter part.
FirstOrDefaultAsync
doesn't throw if there's more than one entity that fits the filter
part.
- 接受主键
- 针对查找具有主键的实体进行了优化,方法是返回
如果实体被跟踪,则不会访问数据库。
- 无法将
include
方法与 FindAsync 一起使用。
- Returns 如果未找到匹配项,则为默认值。
- 接受表达。
- 如果需要相关实体,最好选择 FindAsync。
- Returns 如果未找到匹配项,则为默认值。
- 接受表达。
- Returns 如果未找到匹配项,则为默认值。
- 如果找到多个匹配项,则抛出异常。
我们有 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 文档是这样说的:
Asynchronously finds an entity with the given primary key values. If an entity with the given primary key values exists in the context, then it is returned immediately without making a request to the store. Otherwise, a request is made to the store for an entity with the given primary key values and this entity, if found, is attached to the context and returned. If no entity is found in the context or the store, then null is returned.
所以我的问题是,如果我们给定的用于 FirstOrDefault()
、SingleOrDefault()
和 FindAsync()
的条件是主键,我们有什么实际区别吗?
我的想法是,第一次使用它们总是命中数据库,但是下一次调用呢?。并且可能 EFCore 可以使用相同的上下文来获取 FirstOrDefault()
和 SingleOrDefault()
的值,就像它为 FindAsync()
、maybe?.[=28 所做的那样=]
查找异步
In much of the scaffolded code, FindAsync can be used in place of FirstOrDefaultAsync.
SingleOrDefaultAsync
fetches more data and does unnecessary work. throws an exception if there's more than one entity that fits the filter part.
FirstOrDefaultAsync
doesn't throw if there's more than one entity that fits the filter part.
- 接受主键
- 针对查找具有主键的实体进行了优化,方法是返回 如果实体被跟踪,则不会访问数据库。
- 无法将
include
方法与 FindAsync 一起使用。 - Returns 如果未找到匹配项,则为默认值。
- 接受表达。
- 如果需要相关实体,最好选择 FindAsync。
- Returns 如果未找到匹配项,则为默认值。
- 接受表达。
- Returns 如果未找到匹配项,则为默认值。
- 如果找到多个匹配项,则抛出异常。