LINQ where 子句中的 async/await 不起作用

2023-12-28

我试图在 LINQ 语句中进行异步数据库查询,但遇到错误。下面的代码在没有 async/await 的情况下运行良好

    var newEntities = _repositoryMapping.Mapper.Map<List<Entry>>(entries);

    newEntities = newEntities.Where(async e => await !_context.Entries.AnyAsync(c => c.Id == e.Id)).ToList();

严重性代码 说明 项目文件行抑制状态 错误 CS4010 无法将异步 lambda 表达式转换为委托类型 'Func'。异步 lambda 表达式可能会返回 void、Task 或 Task,其中任何一个都不能转换为 '函数'

除了将其分解为 foreach 循环之外,我怎样才能使其与 async/await 一起工作?


如果您关心性能,代码应该更智能。您只需发送一个查询并检查数据库中已存在的内容。

准备好的扩展可以以通用方式做到这一点:

newEntities = (await newEntities.FilterExistentAsync(_context.Entries, e => e.Id)).ToList();

实施并不那么复杂

public static class QueryableExtensions
{
    public static async Task<IEnumerable<T>> FilterExistentAsync<T, TProp>(this ICollection<T> items,
        IQueryable<T> dbQuery, Expression<Func<T, TProp>> prop, CancellationToken cancellationToken = default)
    {
        var propGetter = prop.Compile();
        var ids = items.Select(propGetter).ToList();
        var parameter = prop.Parameters[0];

        var predicate = Expression.Call(typeof(Enumerable), "Contains", new[] { typeof(TProp) }, Expression.Constant(ids), prop.Body);
        var predicateLambda = Expression.Lambda(predicate, parameter);

        var filtered = Expression.Call(typeof(Queryable), "Where", new[] {typeof(T)}, dbQuery.Expression,
            predicateLambda);

        var selectExpr = Expression.Call(typeof(Queryable), "Select", new[] {typeof(T), typeof(TProp)}, filtered, prop);
        var selectQuery = dbQuery.Provider.CreateQuery<TProp>(selectExpr);

        var existingIds = await selectQuery.ToListAsync(cancellationToken);

        return items.Where(i => !existingIds.Contains(propGetter(i)));
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LINQ where 子句中的 async/await 不起作用 的相关文章

随机推荐