Created
July 12, 2012 01:05
-
-
Save jacobsimeon/3094933 to your computer and use it in GitHub Desktop.
IQueryable Extensions for ordering by a property specified by a string
This file contains 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 System; | |
using System.Collections.Generic; | |
using System.Data.Objects; | |
using System.Linq; | |
using System.Linq.Expressions; | |
using System.Text; | |
namespace JacobSimeon.Extensions | |
{ | |
public static class IQueryableExtensions | |
{ | |
/// <summary> | |
/// Uses .Skip() and .Take() to get a PageOf<T> | |
/// </summary> | |
/// <param name="queryable">Executes the query to get a page and also the total count.</param> | |
/// <param name="currentPage">1-based page number</param> | |
/// <param name="itemsPerPage">Number of items on each page</param> | |
/// <returns></returns> | |
public static PageOf<T> GetPage<T>(this IQueryable<T> queryable, int currentPage, int itemsPerPage) | |
{ | |
var itemsToSkip = (currentPage - 1)*itemsPerPage; | |
var totalItems = queryable.LongCount(); | |
var pageData = queryable.Skip(itemsToSkip).Take(itemsPerPage).ToList(); | |
var p = new PageOf<T>(pageData, currentPage, itemsPerPage, totalItems); | |
return p; | |
} | |
public static IQueryable<T> Include<T>(this IQueryable<T> obj, string path) | |
{ | |
if (obj is ObjectQuery<T>) | |
return (obj as ObjectQuery<T>).Include(path); | |
return obj; | |
} | |
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string property) | |
{ | |
return ApplyOrder<T>(source, property, "OrderBy"); | |
} | |
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string property) | |
{ | |
return ApplyOrder<T>(source, property, "OrderByDescending"); | |
} | |
public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string property) | |
{ | |
return ApplyOrder<T>(source, property, "ThenBy"); | |
} | |
public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source, string property) | |
{ | |
return ApplyOrder<T>(source, property, "ThenByDescending"); | |
} | |
private static IOrderedQueryable<T> ApplyOrder<T> | |
(this IQueryable<T> queryable, string propertyName, string sortMethodName) | |
{ | |
//build an expression tree that can be passed as lambda to IQueryable#OrderBy | |
var type = typeof (T); | |
var paramExpression = Expression.Parameter(type, "parameterExpression"); | |
var property = type.GetProperty(propertyName); | |
var propertyExpression = Expression.Property(paramExpression, property); | |
var lambdaType = typeof (Func<,>).MakeGenericType(type, property.PropertyType); | |
var lambdaExpression = Expression.Lambda(lambdaType, propertyExpression, paramExpression); | |
// dynamically generate a method with the correct type parameters | |
var queryableType = typeof (Queryable); | |
var orderByMethod = queryableType.GetMethods() | |
.Single(m => m.Name == sortMethodName && | |
m.IsGenericMethodDefinition | |
&& m.GetGenericArguments().Length == 2 | |
&& m.GetParameters().Length == 2) | |
.MakeGenericMethod(type, property.PropertyType); | |
var result = orderByMethod.Invoke(null, new object[] {queryable, lambdaExpression}); | |
return (IOrderedQueryable<T>) result; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How do I use this CODE?Please