我们有三种不同的方法从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()
这是微软文档所说的:
异步查找具有给定主键值的实体。如果上下文中存在具有给定主键值的实体,则会立即返回该实体而不向商店发出请求。否则,向具有给定主键值的实体的商店发出请求,并且如果找到该实体,则将该实体附加到上下文并返回。如果在上下文或存储中找不到实体,则返回null。
所以我的问题是,如果我们给出的条件用于FirstOrDefault()
,SingleOrDefault()
和FindAsync()
是主键,我们是否有任何实际的区别?
我认为他们第一次使用它们总是击中数据库,但下一次调用呢?也许EFCore可以使用相同的上下文来获取FirstOrDefault()
和SingleOrDefault()
的值,就像它对FindAsync()
一样,也许?
FindAsync
在大多数脚手架代码中,可以使用FindAsync代替FirstOrDefaultAsync。
SingleOrDefaultAsync
获取更多数据并执行不必要的工作。如果有多个实体适合过滤器部分,则抛出异常。
FirstOrDefaultAsync
如果有多个实体适合过滤器部分,则不会抛出。