using System;
using System.Linq;
using System.Linq.Expressions;
namespace Ems.BusinessTracker.Common.Linq
{
public static class LinqExtensions
{
/// Orders the sequence by specific column and direction.
/// The query.
/// The sort column.
/// if set to true [ascending].
public static IQueryable OrderBy(this IQueryable query, string sortColumn, string direction)
{
string methodName = string.Format("OrderBy{0}",
direction.ToLower() == "asc" ? "" : "descending");
ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
MemberExpression memberAccess = null;
foreach (var property in sortColumn.Split('.'))
memberAccess = MemberExpression.Property
(memberAccess ?? (parameter as Expression), property);
LambdaExpression orderByLambda = Expression.Lambda(memberAccess, parameter);
MethodCallExpression result = Expression.Call(
typeof(Queryable),
methodName,
new[] { query.ElementType, memberAccess.Type },
query.Expression,
Expression.Quote(orderByLambda));
return query.Provider.CreateQuery(result);
}
public static IQueryable Where(this IQueryable query,
string column, object value, WhereOperation operation)
{
if (string.IsNullOrEmpty(column))
return query;
ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
MemberExpression memberAccess = null;
foreach (var property in column.Split('.'))
memberAccess = MemberExpression.Property
(memberAccess ?? (parameter as Expression), property);
//change param value type
//necessary to getting bool from string
ConstantExpression filter = Expression.Constant
(
Convert.ChangeType(value, memberAccess.Type)
);
//switch operation
Expression condition = null;
LambdaExpression lambda = null;
switch (operation)
{
//equal ==
case WhereOperation.Equal:
condition = Expression.Equal(memberAccess, filter);
lambda = Expression.Lambda(condition, parameter);
break;
//not equal !=
case WhereOperation.NotEqual:
condition = Expression.NotEqual(memberAccess, filter);
lambda = Expression.Lambda(condition, parameter);
break;
//string.Contains()
case WhereOperation.Contains:
//condition = Expression.Call(memberAccess,
// typeof(string).GetMethod("Contains"),
// Expression.Constant(value));
//lambda = Expression.Lambda(condition, parameter);
var toLower = Expression.Call(memberAccess,
typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
condition = Expression.Call(toLower,
typeof(string).GetMethod("Contains"),
Expression.Constant(value.ToString().ToLower()));
lambda = Expression.Lambda(condition, parameter);
break;
}
MethodCallExpression result = Expression.Call(
typeof(Queryable), "Where",
new[] { query.ElementType },
query.Expression,
lambda);
return query.Provider.CreateQuery(result);
}
}
}