シート順序のカラムを動的に指定(IQueryable)

渡したカラム名でOrderBy句を作ります。

    public static class QueryableExtension
    {
        public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string column)
        {
            return OrderBy(source, column, "OrderBy");
        }

        public static IQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string column)
        {
            return OrderBy(source, column, "OrderByDescending");
        }

        public static IQueryable<T> ThenBy<T>(this IQueryable<T> source, string column)
        {
            return OrderBy(source, column, "ThenBy");
        }

        public static IQueryable<T> ThenByDescending<T>(this IQueryable<T> source, string column)
        {
            return OrderBy(source, column, "ThenByDescending");
        }

        private static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string command, string column)
        {
            var type = typeof(T);
            var property = type.GetProperty(column);
            var parameter = Expression.Parameter(type, "p");
            var propertyAccess = Expression.MakeMemberAccess(parameter, property);
            var orderByExpression = Expression.Lambda(propertyAccess, parameter);
            var resultExpression = Expression.Call(typeof(Queryable), command, new[] { type, property.PropertyType },
                                          source.Expression, Expression.Quote(orderByExpression));
            return source.Provider.CreateQuery<T>(resultExpression);
        }
    }

実行すると

var q = Context.People.Where(x => x.DeletedOn == null);
q = q.OrderBy("Id").ThenBy("Name").ThenByDescending("Age");

結果はこんなクエリです。

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Age] AS [Age]
    [Extent1].[DeletedOn] AS [DeletedOn]
    FROM [dbo].[People] AS [Extent1]
WHERE [Extent1].[DeletedOn] IS NULL
ORDER BY [Extent1].[Id] DESC, [Extent1].[Name] ASC, [Extent1].[Age] DESC

Comments are closed.

Post Navigation