I have a method that calls Entity Framework functions. It is responsible for sending the "select clause", "order by clause" and possible includes (considering that I'm using lazy loading). The method looks like this:
public IEnumerable<TReturn> GetAll<TReturn, TOrderKey>(
Expression<Func<TEntity, TReturn>> selectExp,
Expression<Func<TEntity, TOrderKey>> orderbyExp,
Boolean descending,
params Expression<Func<TEntity, Object>>[] includeExps)
{
var query = DbSet.AsQueryable();
query = !descending ? query.OrderBy(orderByExp) : query.OrderByDescending(orderByExp);
if (includeExps != null)
query = includeExps.Aggregate(query, (current, exp) => current.Include(exp));
return query.Select(selectExp).ToList();
}
When I call:
_service.GetAll(i => new { i.Name}, i => i.Name, false, null);
It works fine! That is the generated SQL is the exactly as I wanted.
However, considering a real scenario (in my case I'm using asp.net mvc), I have an Action method that gets the order parameter from the client.
That is the method:
public JsonResult GetAllUsers(string sortColumn, bool sortDescending)
{
//sortColumn string must be translated in a Expression
var users = _service.GetAll(i => new { i.Name, i.Email }, i => i.Name, sortDescending, null);
//
//
}
My first attempt was to create an expression for every column, like this:
public JsonResult GetAllUsers(string sortColumn, bool sortDescending)
{
//I don't what is the Type that I should put here
//It can be anything, like: Expression<Func<User, String>>,
//Expression<Func<User, Guid>>, Expression<Func<User, Int>>
?Type? orderExp;
switch(sortColumn)
{
case "UserId":
//Expression<Func<User, Guid>>
orderExp = i => i.UserId;
break;
case "Name":
//Expression<Func<User, String>>
orderExp = i => i.Email;
break;
}
//sortColumn string must be translated in a Expression
var users = _service.GetAll(i => new { i.Name, i.Email }, orderExp, sortDescending, null);
//
//
}
I want to create an expression based on sortProperty, there's a lot of information about it over the stackoverflow, however (see the action method) the variable must be typed before the process. The GetAll method can't be called inside every "case" because it returns an anonymous type.
I can't convert all columns to Expression<Func<User, Object>>
because entity framework does not support it.
Linq.Dynamic should help, but I don't want to use string parameters.