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); } } }