繁体   English   中英

在Linq查询中对数据进行排序

[英]Sorting data in Linq query

我有3个项目要按Linq排序。

这三个项目是

  1. 1.1 AAAAAA
  2. 10.1 AAAAA
  3. 1.11 AAAAA
  4. 9.1 AAAAAA

排序后的列表应为

  1. 1.1 AAAAA
  2. 1.11 AAAA
  3. 9.1 AAAAA
  4. 10.1 AAAA

这是我的代码:

var progTypes = (from mnuit in entities.MENU_ITEM
                 join mnu in entities.MENU on mnuit.MENU_ID equals mnu.MENU_ID
                 join prog in entities.PROG on mnuit.MENU_ITEM_ID equals prog.PROG_TYP_ID
                 where (mnuit.MENU_ITEM_CD == programmodel.selectedProgram && mnu.MENU_NM == "PROG_TYP_ID")
                 select new ProgramModel.lstProgTypes
                        {
                            PROG_ID = prog.PROG_ID,
                            PROG_NBR = prog.PROG_NBR,
                            PROG_NM = prog.PROG_NM,
                            PROG_MAX_AMT = prog.PROG_MAX_AMT,
                            PROG_START_DT = prog.PROG_START_DT,
                            PROG_END_DT = prog.PROG_END_DT
                        }).OrderBy(m => m.PROG_NM)
                          .ToList();

progModel.mProgTypes = progTypes;

你们能帮忙吗

看起来该字符串代表了某种本质上是复合的东西。 处理此类情况的理想方法不是存储复合材料,而是存储各个零件。 在您的情况下,这意味着在三个单独的属性中存储一个数字,另一个数字和一个字符串。

但是,这并非总是可能的,可能是因为您正在处理的旧系统中选择了较差的设计,而现在您受其困扰。 处理这种情况的一种方法是将数据带入内存,并使用自定义IComparer<T>对其进行排序。

首先从查询中删除OrderBy(...) 由于您已经调用ToList() ,因此progTypes将在内存中存储其所有元素。 这就是您想要的方式。 现在,您可以定义一个自定义比较器,并执行以下操作:

progTypes = progTypes.OrderBy(m => m.PROG_NM, new NmComparer()).ToList();

“魔术”进入NmComparer

internal class NmComparer : IComparer<string> {
    public int Compare(string a, string b) {
        var tokA = a.Split('.', ' ');
        var tokB = b.Split('.', ' ');
        int res = int.Parse(tokA[0]).CompareTo(int.Parse(tokB[0]));
        if (res != 0) return res;
        res = int.Parse(tokA[1]).CompareTo(int.Parse(tokB[1]));
        if (res != 0) return res;
        return tokA[2].CompareTo(tokB[2]);
    }
}

比较器假定PROG_NM具有三个部分-两个int和一个string 它在一个点和一个空格上将双方分开,然后比较从左到右的结果,并优先考虑左侧的令牌。

如果您真的必须将所有内容存储在一个字段中。 基本上我只做三种。 我添加了更多示例,以使其工作原理更清晰。

var list = new List<string>
{
    "1.1 AAAAAA",
    "10.1 AAAAA",
    "1.12 AAAAA",
    "1.11 AAAAA",
    "9.1 BAAAAA",
    "9.1 AAAAAA"
};

var result = from s in list
             let indexOfDot = s.IndexOf('.')
             let indexOfSpace = s.IndexOf(' ')
             orderby s.Substring(indexOfSpace)
             orderby Convert.ToInt32(s.Substring(indexOfDot + 1, indexOfSpace - indexOfDot))
             orderby Convert.ToInt32(s.Substring(0, indexOfDot))
             select s;

您可以在LINQPad测试- http://share.linqpad.net/8p23tu.linq

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM