如何解决LINQ按空列升序,其中顺序升序,空值应为最后
|| 我正在尝试按价格对产品列表进行排序。 结果集需要在“ 0”列中按价格从低到高列出产品。但是,此列可以为空。 我可以按照降序对列表进行排序,如下所示: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
但是我不知道如何按升序排序。
// i\'d like: 100,102,null
解决方法
尝试将两个列按相同的顺序排列。
orderby p.LowestPrice.HasValue descending,p.LowestPrice
否则,每个orderby都是对集合的单独操作,每次都会对其进行重新排序。
这应该先对值排序,然后“然后”对值排序。
, 确实有助于理解LINQ查询语法以及如何将其转换为LINQ方法调用。
原来是
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);
显然这不是您想要的。按descending
顺序按Product.LowestPrice.HasValue
排序,然后按descending
顺序按Product.LowestPrice
重新排序整个集合。
你想要的是
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;
有关从查询语法到方法调用的转换的详细信息,请参见语言规范。说真的阅读。
, 字符串值的解决方案确实很奇怪:
.OrderBy(f => f.SomeString == null).ThenBy(f => f.SomeString)
起作用的唯一原因是因为第一个表达式OrderBy()
对bool
值进行排序:true
/false
。首先是false
结果,然后是true
结果(可为null),而ѭ19alphabet将按字母顺序对非null值进行排序。
所以,我喜欢做一些更易读的事情,例如:
.OrderBy(f => f.SomeString ?? \"z\")
如果SomeString
为空,则将其替换为\"z\"
,然后按字母顺序对所有内容进行排序。
注意:这不是最终解决方案,因为since22ѭ比z值(如zebra
)先行。
2016年9月6日更新-关于@jornhd注释,这确实是一个不错的解决方案,但仍然有些复杂,因此我建议将其包装在Extension类中,例如:
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);
, 在这种情况下,我还有另一种选择。
我的列表是objList,我必须排序,但最后必须为null。
我的决定:
var newList = objList.Where(m=>m.Column != null)
.OrderBy(m => m.Column)
.Concat(objList.where(m=>m.Column == null));
, 我试图为此找到一种LINQ解决方案,但无法从这里的答案中得出答案。
我的最终答案是:
.OrderByDescending(p => p.LowestPrice.HasValue).ThenBy(p => p.LowestPrice)
, 我的决定:
Array = _context.Products.OrderByDescending(p => p.Val ?? float.MinValue)
, 这是我想出的,因为我正在使用扩展方法,而且我的项目是字符串,因此没有“ 30”:
.OrderBy(f => f.SomeString == null).ThenBy(f => f.SomeString)
这适用于内存中的LINQ 2对象。我没有使用EF或任何数据库ORM对其进行测试。
, 下面是扩展方法,如果您想对keySelector的child属性进行排序,请检查是否为null。
public static IOrderedEnumerable<T> NullableOrderBy<T>(this IEnumerable<T> list,object> parentKeySelector,object> childKeySelector)
{
return list.OrderBy(v => parentKeySelector(v) != null ? 0 : 1).ThenBy(childKeySelector);
}
和简单的使用它像:
var sortedList = list.NullableOrderBy(x => x.someObject,y => y.someObject?.someProperty);
, 这是另一种方式:
//Acsending
case \"SUP_APPROVED_IND\": qry =
qry.OrderBy(r => r.SUP_APPROVED_IND.Trim() == null).
ThenBy(r => r.SUP_APPROVED_IND);
break;
//….
//Descending
case \"SUP_APPROVED_IND\": qry =
qry.OrderBy(r => r.SUP_APPROVED_IND.Trim() == null).
ThenByDescending(r => r.SUP_APPROVED_IND);
break;
SUP_APPROVED_IND is char(1) in Oracle db.
请注意,在Oracle数据库中将“ 36”视为“ 37”。
详细信息请参见:如何在实体框架中查询空值?
, 另一个选择(在我们的情况下很方便):
我们有一个用户表,存储ADName,LastName,FirstName
用户应按字母顺序
也没有名字/姓氏的帐户,基于其ADName-但在用户列表的末尾
ID为\“ 0 \”(\“无选择\”)的虚拟用户应始终位于最高位置。
我们更改了表架构,并添加了“ SortIndex \”列,该列定义了一些排序组。 (我们的差距为5,因此我们可以稍后插入组)
ID | ADName | First Name | LastName | SortIndex
0 No Selection null null | 0
1 AD\\jon Jon Doe | 5
3 AD\\Support null null | 10
4 AD\\Accounting null null | 10
5 AD\\ama Amanda Whatever | 5
现在,从查询角度来看,它将是:
SELECT * FROM User order by SortIndex,FirstName,AdName;
在方法表达式中:
db.User.OrderBy(u => u.SortIndex).ThenBy(u => u.LastName).ThenBy(u => u.FirstName).ThenBy(u => u.AdName).ToList();
得到预期的结果:
ID | ADName | First Name | LastName | SortIndex
0 No Selection null null | 0
5 AD\\ama Amanda Whatever | 5
1 AD\\jon Jon Doe | 5
4 AD\\Accounting null null | 10
3 AD\\Support null null | 10
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。