Linq动态OrderBy排序

方法:

/// <summary>
/// 扩展Linqstring字段排序
/// </summary>
public static class StringFieldSorting
{
    #region Private expression tree helpers
    private static LambdaExpression GenerateSelector<TEntity>(String propertyName, out Type resultType) where TEntity : class
    {
        PropertyInfo property;
        Expression propertyAccess;
        var parameter = Expression.Parameter(typeof(TEntity), "Entity");
            
        if (propertyName.Contains('.'))
        {
            String[] childProperties = propertyName.Split('.');
            property = typeof(TEntity).GetProperty(childProperties[0]);
            propertyAccess = Expression.MakeMemberAccess(parameter, property);
            for (int i = 1; i < childProperties.Length; i++)
            {
                property = property.PropertyType.GetProperty(childProperties[i]);
                propertyAccess = Expression.MakeMemberAccess(propertyAccess, property);
            }
        }
        else
        {
            property = typeof(TEntity).GetProperty(propertyName);
            propertyAccess = Expression.MakeMemberAccess(parameter, property);
        }

        resultType = property.PropertyType;

        return Expression.Lambda(propertyAccess, parameter);
    }
    private static MethodCallExpression GenerateMethodCall<TEntity>(IQueryable<TEntity> source, string methodName, String fieldName) where TEntity : class
    {
        Type type = typeof(TEntity);
        Type selectorResultType;
        LambdaExpression selector = GenerateSelector<TEntity>(fieldName, out selectorResultType);
        MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName,
        new Type[] { type, selectorResultType },
        source.Expression, Expression.Quote(selector));
        return resultExp;
    }
    #endregion

    public static IOrderedQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string fieldName) where TEntity : class
    {
        MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "OrderBy", fieldName);
        return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
    }

    public static IOrderedQueryable<TEntity> OrderByDescending<TEntity>(this IQueryable<TEntity> source, string fieldName) where TEntity : class
    {
        MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "OrderByDescending", fieldName);
        return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
    }

    public static IOrderedQueryable<TEntity> ThenBy<TEntity>(this IOrderedQueryable<TEntity> source, string fieldName) where TEntity : class
    {
        MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "ThenBy", fieldName);
        return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
    }

    public static IOrderedQueryable<TEntity> ThenByDescending<TEntity>(this IOrderedQueryable<TEntity> source, string fieldName) where TEntity : class
    {
        MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "ThenByDescending", fieldName);
        return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
    }
    public static IOrderedQueryable<TEntity> OrderUsingSortExpression<TEntity>(this IQueryable<TEntity> source, string sortExpression) where TEntity : class
    {
        String[] orderFields = sortExpression.Split(',');
        IOrderedQueryable<TEntity> result = null;
        for (int currentFieldIndex = 0; currentFieldIndex < orderFields.Length; currentFieldIndex++)
        {
            String[] expressionPart = orderFields[currentFieldIndex].Trim().Split(' ');
            String sortField = expressionPart[0];
            Boolean sortDescending = (expressionPart.Length == 2) && (expressionPart[1].Equals("DESC", StringComparison.OrdinalIgnoreCase));
            if (sortDescending)
            {
                result = currentFieldIndex == 0 ? source.OrderByDescending(sortField) : result.ThenByDescending(sortField);
            }
            else
            {
                result = currentFieldIndex == 0 ? source.OrderBy(sortField) : result.ThenBy(sortField);
            }
        }
        return result;
    }
}

调用:

var query = (from d in ((VinnoTech.Gaia2.DB.g2_dsource[])result)
            join p in WebApiApplication.entities.g2_propnames
            on d.dsource_item equals p.prop_name
            orderby sidx
            select new
            {
                d.dsource_id,
                d.dsource_name,
                dsource_item = p.prop_description,
                d.dsource_description,
                dsource_status = d.dsource_status == "1" ? "启用" : "禁用",
                d.dsource_expiredday,
                dsource_alarmhigh = (d.dsource_alarmhigh == -65535 || d.dsource_alarmhigh == 65535) ? "未禁用" : d.dsource_alarmhigh.ToString(),
                dsource_alarmlow = (d.dsource_alarmlow == -65535 || d.dsource_alarmhigh == 65535) ? "未禁用" : d.dsource_alarmhigh.ToString(),
                dsource_alarmdeltadata = (d.dsource_alarmdeltadata == -65535 || d.dsource_alarmhigh == 65535) ? "未禁用" : d.dsource_alarmhigh.ToString(),
                dsource_alarmidle = (d.dsource_alarmidle == -65535 || d.dsource_alarmhigh == 65535) ? "未禁用" : d.dsource_alarmhigh.ToString(),
                d.dsource_formula,
                dsource_updatetime = d.dsource_updatetime.ToString("yyyy-MM-dd HH:mm:ss")
            }).AsQueryable();
            
page = page <= query.Count() / rows + 1 ? page : 1;

query = query.OrderUsingSortExpression("dsource_name asc,dsource_item desc").Skip(rows * (page - 1)).Take(rows);
posted on 2013-04-03 14:45  一路前行  阅读(1996)  评论(0编辑  收藏  举报