首页 > 解决方案 > SingleOrDefaultAsync:它实际上是什么意思?

问题描述

作为一个处理“旧” C# 并且现在随着我迁移到 ASP.NET 而加快速度的人,我想知道是否有人可以通过这个简单的示例帮助我。
内置向导生成如下代码:

var product = await _context.Products.SingleOrDefaultAsync(m => m.ProductId == id);

现在,我从 Lamba 表达式中得到什么m => m.ProductId == id?为什么不能这样:

var product = await _context.Products.SingleOrDefaultAsync(m.ProductId);

我正在尝试阅读文档,但这只会增加我的困惑。它记录了查询是:

public static Task<TSource> SingleOrDefaultAsync<TSource>(
    this IQueryable<TSource> source
)

所以......它返回一个任务是什么意思?那是通用的吗?<TSource>3次在那里做什么?

任何可以澄清这一点的一般阅读的参考都将受到高度赞赏......这些是所谓的表达式树吗?这是林克……?我从哪里开始?ETC...

谢谢!

标签: c#linqasync-await

解决方案


因此,正确重载的文档SingleOrDefaultAsync的签名为:

public static Task<TSource> SingleOrDefaultAsync<TSource>(
    this IQueryable<TSource> source,
    Expression<Func<TSource, bool>> predicate
)

这是前面第一个参数所表示的扩展方法。this扩展方法是一种静态方法,使用(语法上)就好像它是成员方法一样。

因此,第一个参数source将是_context.Products.

第二个参数是一个Expression<Func<>>,这意味着编译器会将传入的lambda 表达式Expression转换为表示代码的数据结构。lambda 表达式用于允许您为正在执行的查询指定任何所需的条件,例如您可能必须m => m.ProductId == id && m.Active排除未激活的产品。

因此,您的第二个参数predicate将是m => m.ProductId == idExpression棵树,该方法可以将其转换为 SQL 并发送到数据库。

最后,返回类型Task<>表示该方法将异步执行,您将立即获得一个Task对象,一旦它可用,您就可以使用它来获取实际结果。

调用await结果会导致此方法在执行中暂停,控制权返回给调用者(它也获取一个对象),并且一旦完成Task,此方法就会恢复。Task


推荐阅读