Created
April 27, 2017 13:57
-
-
Save eshapovalova/e95efe3f2c2678149ac7b7dc9f836f37 to your computer and use it in GitHub Desktop.
QueryExtensions helper for dynamic build LINQ queries using Extensions and dynamic LINQ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using KindergartenApp.Core.Extensions; | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Linq.Dynamic; | |
| using System.Linq.Expressions; | |
| using System.Reflection; | |
| using KindergartenApp.Core.Filtering; | |
| namespace KindergartenApp.Core.Extensions | |
| { | |
| public static class QueryableExtensions | |
| { | |
| public static IQueryable<T> SortIQueryable<T>(this IQueryable<T> data, string fieldName, string sortOrder) | |
| { | |
| if (string.IsNullOrWhiteSpace(fieldName)) return data; | |
| if (string.IsNullOrWhiteSpace(sortOrder)) return data; | |
| var param = Expression.Parameter(typeof(T), "i"); | |
| MemberExpression property = null; | |
| string[] fieldNames = fieldName.Split('.'); | |
| foreach (string filed in fieldNames) | |
| { | |
| property = property == null ? Expression.Property(param, filed) : Expression.Property(property, filed); | |
| } | |
| if (property.Type.IsValueType) | |
| { | |
| Expression valConvertion = Expression.ConvertChecked(property, property.Type); | |
| if (property.Type == typeof(int)) | |
| { | |
| var myValSortExpression = Expression.Lambda<Func<T, int>>(valConvertion, param); | |
| return (sortOrder == "desc") ? data.OrderByDescending(myValSortExpression) | |
| : data.OrderBy(myValSortExpression); | |
| } | |
| if (property.Type == typeof(double)) | |
| { | |
| var myValSortExpression = Expression.Lambda<Func<T, double>>(valConvertion, param); | |
| return (sortOrder == "desc") ? data.OrderByDescending(myValSortExpression) | |
| : data.OrderBy(myValSortExpression); | |
| } | |
| if (property.Type == typeof(long)) | |
| { | |
| var myValSortExpression = Expression.Lambda<Func<T, long>>(valConvertion, param); | |
| return (sortOrder == "desc") ? data.OrderByDescending(myValSortExpression) | |
| : data.OrderBy(myValSortExpression); | |
| } | |
| if (property.Type == typeof(byte)) | |
| { | |
| var myValSortExpression = Expression.Lambda<Func<T, byte>>(valConvertion, param); | |
| return (sortOrder == "desc") ? data.OrderByDescending(myValSortExpression) | |
| : data.OrderBy(myValSortExpression); | |
| } | |
| if (property.Type == typeof(bool)) | |
| { | |
| var myValSortExpression = Expression.Lambda<Func<T, bool>>(valConvertion, param); | |
| return (sortOrder == "desc") ? data.OrderByDescending(myValSortExpression) | |
| : data.OrderBy(myValSortExpression); | |
| } | |
| if (property.Type == typeof(bool?)) | |
| { | |
| var myValSortExpression = Expression.Lambda<Func<T, bool?>>(valConvertion, param); | |
| return (sortOrder == "desc") ? data.OrderByDescending(myValSortExpression) | |
| : data.OrderBy(myValSortExpression); | |
| } | |
| if (property.Type == typeof(DateTime)) | |
| { | |
| var myValSortExpression = Expression.Lambda<Func<T, DateTime>>(valConvertion, param); | |
| return (sortOrder == "desc") ? data.OrderByDescending(myValSortExpression) | |
| : data.OrderBy(myValSortExpression); | |
| } | |
| if (property.Type == typeof(DateTime?)) | |
| { | |
| var myValSortExpression = Expression.Lambda<Func<T, DateTime?>>(valConvertion, param); | |
| return (sortOrder == "desc") ? data.OrderByDescending(myValSortExpression) | |
| : data.OrderBy(myValSortExpression); | |
| } | |
| } | |
| Expression conversion = Expression.ConvertChecked(property, property.Type); | |
| var mySortExpression = Expression.Lambda<Func<T, object>>(conversion, param); | |
| return (sortOrder == "desc") ? data.OrderByDescending(mySortExpression) | |
| : data.OrderBy(mySortExpression); | |
| } | |
| public static IQueryable<T> WhereQueryable<T>(this IQueryable<T> data, IList<FilterModel> filters) | |
| { | |
| var separator = " || "; | |
| var itemstType = typeof(T); | |
| var containsPredicate = new List<string>(); | |
| var numbersPredicate = new List<string>(); | |
| var dateTimePredicate = new List<string>(); | |
| foreach (var filter in filters) | |
| { | |
| var isNested = filter.Name.Contains("."); | |
| if (isNested) | |
| { | |
| containsPredicate.Add($"{filter.Name}.Contains(\"{filter.Term}\")"); | |
| continue; | |
| } | |
| var propertyType = itemstType.GetProperty(filter.Name); | |
| if (propertyType != null) | |
| { | |
| var filterType = propertyType.PropertyType; | |
| if (filterType == typeof(string)) | |
| { | |
| containsPredicate.Add($"{filter.Name}.Contains(\"{filter.Term}\")"); | |
| } | |
| if (filterType == typeof(long) || filterType == typeof(int) || filterType == typeof(byte)) | |
| { | |
| numbersPredicate.Add($"{filter.Name} = {filter.Term}"); | |
| } | |
| if (filterType == typeof(DateTime)) | |
| { | |
| // itmes = items.Where(string.Format("{0} > @0", searchField), | |
| //DateTime.Parse(searchString)); | |
| var dt = DateTime.Parse(filter.Term); | |
| //dateTimePredicate.Add($"{filter.Name} = Date({dt.Date.Year}, {dt.Date.Month}, {dt.Date.Day})"); | |
| //dateTimePredicate.Add($"{filter.Name} == DateTime.Parse(\"{filter.Term}\")"); | |
| //dateTimePredicate.Add($"DbFunctions.TruncateTime({filter.Name}) == {dt}"); | |
| } | |
| } | |
| } | |
| var predicate = string.Join(separator, containsPredicate); | |
| if (!string.IsNullOrEmpty(predicate)) | |
| data = data.Where(predicate); | |
| var numPredicate = string.Join(separator, numbersPredicate); | |
| if(!string.IsNullOrEmpty(numPredicate)) | |
| data = data.Where(numPredicate); | |
| var dtPredicate = string.Join(separator, dateTimePredicate); | |
| if (!string.IsNullOrEmpty(dtPredicate)) | |
| data = data.Where(dtPredicate); | |
| return data; | |
| } | |
| public static Expression<Func<T, bool>> False<T>() { return f => false; } | |
| public static Expression<Func<T, bool>> In<T, TValue>(this Expression<Func<T, bool>> predicate, string propertyName, List<TValue> values) | |
| { | |
| var param = predicate.Parameters.Single(); | |
| MemberExpression property = Expression.PropertyOrField(param, propertyName); | |
| var micontain = typeof(List<TValue>).GetMethod("Contains"); | |
| var mc = Expression.Call(Expression.Constant(values), micontain, property); | |
| return Expression.Lambda<Func<T, bool>>(mc, param); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment