首页 > 解决方案 > 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 文档所说的:

异步查找具有给定主键值的实体。如果上下文中存在具有给定主键值的实体,则立即返回它而不向存储区发出请求。否则,将向存储请求具有给定主键值的实体,如果找到该实体,则将其附加到上下文并返回。如果在上下文或存储中未找到实体,则返回 null。

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

我认为第一次使用它们总是命中数据库,但接下来的调用呢?. 也许 EFCore 可以使用相同的上下文来获取 和 的FirstOrDefault()值,也许SingleOrDefault()?.FindAsync()

标签: c#linqef-core-2.0

解决方案


查找异步

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

SingleOrDefaultAsync

获取更多数据并做不必要的工作。如果有多个实体适合过滤器部分,则会引发异常。

FirstOrDefaultAsync

如果有多个实体适合过滤器部分,则不会抛出。

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


推荐阅读