Search code examples
c#lambdalinq-to-sql

How do I overload LINQ IQueryable<TEntity> Where() to accept column name


I would like to modify the following to accept the column name which will be searched in the Where method, something like:

        public TEntity GetEntity(int val)
        {
            TEntity entity = _DbContext.Set<TEntity>()
                   .Where(e => e.Id == val)
                   .FirstOrDefault();
            return entity;
        }

to be changed to

        public TEntity GetEntity(int val, string colName)
        {
            TEntity entity = _DbContext.Set<TEntity>()
                   .WhereWithColName(val, colName)
                   .FirstOrDefault();
            return entity;
        }

Expression trees still too complex for me...


Solution

  • OK, solved it:

    public static IQueryable<TEntity> WhereById<TEntity, TKey>(this IQueryable<TEntity> query, TKey value, string colName)
                where TEntity : class
    {
        var param = Expression.Parameter(typeof(TEntity), "e");
        var propAccess = Expression.PropertyOrField(param, colName);
        var valExpr = Expression.Constant(value);
    
        var predicate = Expression.Equal(propAccess,valExpr);
    
        var predicateLambda = Expression.Lambda<Func<TEntity, bool>>(predicate, param);
    
        return query.Where(predicateLambda);
    }
    

    and the calling function is then:

    public TEntity GetEntity(int val, string colName)
    {
        TEntity entity = _DbContext.Set<TEntity>()
               .WhereById<TEntity, int>(val, colName)
               .FirstOrDefault();
        return entity;
    }