FirstOrDefaultAsync()&SingleOrDefaultAsync()vs FindAsync()EFCore

问题描述 投票:2回答:1

我们有三种不同的方法从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()一样,也许?

c# linq ef-core-2.0
1个回答
3
投票

FindAsync

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

SingleOrDefaultAsync

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

FirstOrDefaultAsync

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

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

© www.soinside.com 2019 - 2024. All rights reserved.