C#Linq OrderBy过滤null或空值为last
我尝试使用自定义orderby扩展方法,我成功地处理了我的代码,但另外我想在结果中列出null或空值或零值,任何人都可以帮我解决这个问题?
这是我对orderby的扩展方法
public static IQueryable OrderBy(this IQueryable q, string SortField, bool isAsc) { //var nullExpr = Expression.Constant(null, typeof(T)); var param = Expression.Parameter(typeof(T), "p"); var prop = Expression.Property(param, SortField); var exp = Expression.Lambda(prop, param); string method = isAsc ? "OrderBy" : "OrderByDescending"; Type[] types = new Type[] { q.ElementType, exp.Body.Type }; var mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp); return q.Provider.CreateQuery(mce); }
提前致谢
不使用扩展方法….
在使用默认String.Compare
之前,创建自定义IComparer
以检查空值。 如果使用标准字符串比较,则第一次检查将返回-1而不是1或1而不是-1。
/// /// Returns -1 instead of 1 if y is IsNullOrEmpty when x is Not. /// public class EmptyStringsAreLast : IComparer { public int Compare(string x, string y) { if (String.IsNullOrEmpty(y) && !String.IsNullOrEmpty(x)) { return -1; } else if (!String.IsNullOrEmpty(y) && String.IsNullOrEmpty(x)) { return 1; } else { return String.Compare(x, y); } } }
将EmptyStringsAreLast
比较器传递给Lambda表达式的OrderBy
。 在此解决方案中,参加比赛的团队应按字母顺序排列,但非关联竞赛条目应在结束时出现。
var entries = repository.Race.Where(e => e.EventId == id) .OrderBy(e => e.TeamName, new EmptyStringsAreLast()) .ThenBy(e => e.LastName) .ThenBy(e => e.FirstName);
最简单的方法是使用
OrderBy(e => String.IsNullOrEmpty(e.TeamName)
这不需要任何扩展方法或自定义IComparer
实现等。
var entries = repository.Race.Where(e => e.EventId == id) .OrderBy(e => String.IsNullOrEmpty(e.TeamName)) .ThenBy(e => e.LastName) .ThenBy(e => e.FirstName);
这个答案可能就是你最初想要的 – 使用你的通用扩展方法:
public static IQueryable OrderByFieldNullsLast (this IQueryable q, string SortField, bool Ascending) { //We are rebuilding .OrderByDescending(p => p.SortField.HasValue).ThenBy(p => p.SortField) //ie sort first by whether sortfield has a value, then by sortfield asc or sortfield desc //create the expression tree that represents the generic parameter to the predicate var param = Expression.Parameter(typeof(T), "p"); //create an expression tree that represents the expression p=>p.SortField.HasValue var prop = Expression.Property(param, SortField); var hasValue = Expression.Property(prop, "HasValue"); var exp = Expression.Lambda(hasValue, param); string method = "OrderByDescending"; Type[] types = new Type[] { q.ElementType, exp.Body.Type }; var orderByCallExpression = Expression.Call(typeof(Queryable), method, types, q.Expression, exp); //now do the ThenBy bit,sending in the above expression to the Expression.Call exp = Expression.Lambda(prop, param); types = new Type[] { q.ElementType, exp.Body.Type }; method = Ascending ? "ThenBy" : "ThenByDescending"; var ThenByCallExpression = Expression.Call(typeof(Queryable), method, types,orderByCallExpression, exp); return q.Provider.CreateQuery (ThenByCallExpression); }
基于Dave Anson的回答,您可以使用Comparer.Create()从lambda创建Comparer。 这是一个通过myString
字符串字段排序unsorted
的示例,最后出现空字符串或空字符串。
var sorted = unsorted.OrderBy(x => x.myString, Comparer.Create((x, y) => { if ( string.IsNullOrEmpty(y) && !string.IsNullOrEmpty(x)) return -1; else if (!string.IsNullOrEmpty(y) && string.IsNullOrEmpty(x)) return +1; else return string.Compare(x, y); }))
(把它们放在第一位,在1
常数上切换标志)
这个对我有用:
上述就是C#学习教程:C#Linq OrderBy过滤null或空值为last分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
private static IQueryable GetOrderQuery (this IQueryable q, BaseFilterCollection filter) { q = q.OrderBy(GetExpression (filter.SortField)); var param = Expression.Parameter(typeof(T), "p"); var prop = Expression.Property(param, filter.SortField); var exp = Expression.Lambda(prop, param); string method = filter.SortDirection == SortDirectionType.Asc ? "ThenBy" : "ThenByDescending"; Type[] types = { q.ElementType, exp.Body.Type }; var rs = Expression.Call(typeof(Queryable), method, types, q.Expression, exp); return q.Provider.CreateQuery (rs); } private static Expression> GetExpression (string sortField) { ParameterExpression param = Expression.Parameter(typeof(T), "p"); Expression prop = Expression.Property(param, sortField); var info = typeof(T).GetProperty(sortField, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); Expression exp = Expression.Equal(prop, info.PropertyType.IsValueType ? Expression.Constant(Activator.CreateInstance(info.PropertyType)) : Expression.Constant(null)); return Expression.Lambda>(exp, param); }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1269362.html