【问题标题】:Overload for LINQ List.Contains() to accept column nameLINQ List.Contains() 重载以接受列名
【发布时间】: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?什么数据库提供商?

标签: c# linq linq-to-sql


【解决方案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);
}

【讨论】:

  • 完美而优雅!也许这是我学习反射的时候了……谢谢!
猜你喜欢
  • 2014-09-07
  • 1970-01-01
  • 2014-11-25
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
相关资源
最近更新 更多