How do I define a SELECT TOP using LINQ with a dynamic query?

c#, lambda, linq, sql

Solution

The parameter is of type:

System.Linq.Expressions.Expression<Func<T, bool>> find

That means it can take a predicate (the "where" clause), and only a predicate. Thus the only bit you can pass in there is the filter:

x => x.ConfigurationReference == "172.16.59.175"

To do what you want, you would need to add the rest of the code in `FindEntities`, so that it becomes:

var val = dataContext.GetTable<T>().Where(find)
              .OrderByDescending(x => x.Date).Take(100).ToList<T>();

(note also that the `Take` should really be after the `OrderByDescending`)

One way you could do that would be:

public static List<T> FindEntities<T>(TrackingDataContext dataContext,
    System.Linq.Expressions.Expression<Func<T, bool>> find,
    Func<IQueryable<T>, IQueryable<T>> additonalProcessing = null
) where T : class
{
    var query = dataContext.GetTable<T>().Where(find);
    if(additonalProcessing != null) query = additonalProcessing(query);
    return query.ToList<T>();
}

and call:

var data = FindEntities(db, x => x.ConfigurationReference == "172.16.58.175",
    q => q.OrderByDescending(x => x.Date).Take(100));

However, frankly I'm not sure what the point of this would be... the caller could do all of that themselves locally more conveniently, without using `FindEntities` at all. Just:

var data = db.GetTable<T>()
             .Where(x => x.ConfigurationReference == "172.16.58.175")
             .OrderByDescending(x => x.Date).Take(100).ToList(); 

or even:

var data = db.SomeTable
             .Where(x => x.ConfigurationReference == "172.16.58.175")
             .OrderByDescending(x => x.Date).Take(100).ToList();

or just:

var data = (from row in db.SomeTable
            where row.ConfigurationReference == "172.16.58.175"
            orderby row.Date descending
            select row).Take(100).ToList();

Problem

I want to pass dynamic lambda expressions to the function below, but I'm not sure how to define the .Take() or .OrderByDescending() on the expression object. If I want to call the function below, then I want to be able to do this: ``` dbprovider.Query = (x => x.ConfigurationReference == "172.16.59.175") .Take(100) .OrderByDescending(x.Date) FindEntities(db, dbprovider.Query) ``` But I can't (this syntax is invalid). Any ideas? ``` public static List<T> FindEntities<T>(TrackingDataContext dataContext, System.Linq.Expressions.Expression<Func<T, bool>> find) where T : class { try { var val = dataContext.GetTable<T>().Where(find).ToList<T>(); return val; } catch (Exception ex) { throw ex; } } ```

Original source