微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

LINQ按空列升序,其中顺序升序,空值应为最后

如何解决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 举报,一经查实,本站将立刻删除。