LINQ List.Contains() 重载以接受列名

Posted

技术标签:

【中文标题】LINQ List.Contains() 重载以接受列名【英文标题】:Overload for LINQ List.Contains() to accept column name 【发布时间】:2021-08-14 10:14:36 【问题描述】:

我想修改以下程序

        public async Task<IActionResult> GetMany(List<int> values)
        
             List<TEntity> entities = await _crudApiDbContext.Set<TEntity>()
                    .Where(entity => values.Contains(entity.Id)).ToListAsync();
             return new OkObjectResult(entities);
        

接受将在 Contains 方法中搜索的列名,例如:

        public async Task<IActionResult> GetMany(List<int> values, string colName)
        
             List<TEntity> entities = await _crudApiDbContext.Set<TEntity>()
                    .Where(entity => values.Contains<TEntity>(colName)).ToListAsync();
             return new OkObjectResult(entities);
        

我尝试过重载 Contains 并使用表达式树,但迷路了...

有什么想法吗?

【问题讨论】:

您使用的是什么 LINQ:LINQ to Objects / SQL / EF 6.x / EF Core 2.0 / 2.1 / 3.x / 5.x / 6.x?什么数据库提供商? 【参考方案1】:

引入以下扩展方法,该方法应该按集合过滤任何实体类型:

public static class QueryableExtensions

    public static IQueryable<TEntity> FilterByList<TEntity, TKey>(this IQueryable<TEntity> query, IEnumerable<TKey> values, string colName) 
        where TEntity : class
    
        var param = Expression.Parameter(typeof(TEntity), "e");
        var propAccess = Expression.PropertyOrField(param, colName);
        var listExpr = Expression.Constant(values);

        var predicate = Expression.Call(typeof(Enumerable), "Contains", new[] typeof(TKey), listExpr,
            propAccess);

        var predicateLambda = Expression.Lambda<Func<TEntity, bool>>(predicate, param);

        return query.Where(predicateLambda);
    

并将您的 GetMany 重写为这个变体:

public async Task<IActionResult> GetMany<TEntity>(List<int> values, string colName)

    var entities = await _crudApiDbContext.Set<TEntity>()
        .FilterByList(values, colName)
        .ToListAsync();
    return new OkObjectResult(entities);

【讨论】:

完美而优雅!也许这是我学习反射的时候了……谢谢!

以上是关于LINQ List.Contains() 重载以接受列名的主要内容,如果未能解决你的问题,请参考以下文章

令人惊讶的性能差异:List.Contains、Sorted List.ContainsKey、DataRowCollection.Contains、Data Table.Select、DataTab

list.contains

java: List.contains() 与手动搜索的性能差异

List.contains() 失败,而 .equals() 工作

List 与 Set 的 contains方法比较

List.contains(Object object)方法