方法:
/// <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);