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
java: List.contains() 与手动搜索的性能差异