LINQ order by null列,其中order是升序,nulls应该是last
我正在尝试按价格sorting产品清单。
结果集需要按列的LowestPrice
按价格从低到高列出产品。 但是,这个列是可以空的。
我可以像这样按降序对列表进行sorting:
var products = from p in _context.Products where p.ProductTypeId == 1 orderby p.LowestPrice.HasValue descending orderby p.LowestPrice descending select p; // returns: 102, 101, 100, null, null
不过,我不知道如何按升序sorting。
// i'd like: 100, 101, 102, null, null
尝试把两列按相同的顺序。
orderby p.LowestPrice.HasValue descending, p.LowestPrice
否则,每个orderby是对集合的单独操作,每次重新sorting。
这应该首先用一个值来sorting,然后是“值”的顺序。
这对理解LINQ查询语法以及如何将其转换为LINQ方法调用确实有帮助。
事实certificate
var products = from p in _context.Products where p.ProductTypeId == 1 orderby p.LowestPrice.HasValue descending orderby p.LowestPrice descending select p;
将被编译器翻译为
var products = _context.Products .Where(p => p.ProductTypeId == 1) .OrderByDescending(p => p.LowestPrice.HasValue) .OrderByDescending(p => p.LowestPrice) .Select(p => p);
这强调不是你想要的。 按Product.LowestPrice.HasValue
的descending
sorting,然后descending
排列Product.LowestPrice.HasValue
对整个集合进行重新sorting。
你想要的是
var products = _context.Products .Where(p => p.ProductTypeId == 1) .OrderByDescending(p => p.LowestPrice.HasValue) .ThenBy(p => p.LowestPrice) .Select(p => p);
您可以使用查询语法来获取
var products = from p in _context.Products where p.ProductTypeId == 1 orderby p.LowestPrice.HasValue descending, p.LowestPrice select p;
有关从查询语法到方法调用的翻译的详细信息,请参阅语言规范。 认真。 阅读。
在这种情况下我有另一种select。 我的列表是objList,我必须sorting,但空值必须是最后的。 我的决定:
var newList = objList.Where(m=>m.Column != null) .OrderBy(m => m.Column) .Concat(objList.where(m=>m.Column == null));
我的决定:
Array = _context.Products.OrderByDescending(p => p.Val ?? float.MinValue)
string值的解决scheme真的很奇怪:
.OrderBy(f => f.SomeString == null).ThenBy(f => f.SomeString)
唯一的原因是因为第一个expression式OrderBy()
对bool
值进行sorting: true
/ false
。 false
结果首先跟着true
结果(可空),然后ThenBy()
按字母顺序sorting非空值。
所以,我更喜欢做一些更具可读性的东西,例如:
.OrderBy(f => f.SomeString ?? "z")
如果SomeString
为null,它将被replace为"z"
,然后按字母顺序sorting。
注意:这不是一个最终的解决scheme,因为"z"
首先比z值更像zebra
。
更新 9/6/2016 – 关于@jornhd评论,这是一个很好的解决scheme,但它仍然有点复杂,所以我会build议把它包装在一个扩展类,如:
public static class MyExtensions { public static IOrderedEnumerable<T> NullableOrderBy<T>(this IEnumerable<T> list, Func<T, string> keySelector) { return list.OrderBy(v => keySelector(v) != null ? 0 : 1).ThenBy(keySelector); } }
简单的使用它就像:
var sortedList = list.NullableOrderBy(f => f.SomeString);
这是我想到的,因为我使用扩展方法,也是我的项目是一个string,因此没有.HasValue
:
.OrderBy(f => f.SomeString == null).ThenBy(f => f.SomeString)
这与内存中的LINQ 2对象一起工作。 我没有用EF或任何DB ORM进行testing。
我试图find一个LINQ的解决scheme,但不能从这里的答案。
我的最后答案是:
.OrderByDescending(p.LowestPrice.HasValue).ThenBy(p.LowestPrice)