Linq语句对list集合中的某个值进行排序


 var tmp1 = db.GetList<T_RECORD>(o => o.VALID_FLAG == true && o.ASSEMBLY_CODE.Equals(selectedSn)).OrderBy(p => p.WS_ID).
            Select(f => new WsRepaired() { WS_ID = f.WS_ID, WORKPIECE_STATUS = f.WORKPIECE_STATUS.GetValueOrDefault(), ID = f.ID }).ToList();


            var tmp2 = db.GetList<T_RECORD_VISION>(o => o.VALID_FLAG == true && o.ASSEMBLY_CODE.Equals(selectedSn)).OrderBy(p => p.WS_ID).
            Select(f => new WsRepaired() { WS_ID = f.WS_ID, WORKPIECE_STATUS = f.WORKPIECE_STATUS.GetValueOrDefault(), ID = f.ID }).ToList();
            foreach (var item in tmp2)
            {
                tmp1.Add(item);

            }
            var test = tmp1.ToList();
            var tmp=test.OrderBy(o=>o.WS_ID).ToList();


我把两个集合合并,再对集合进行排序得到新的集合,可是排序之后在界面上展示的只是两个集合合并的结果,没有排序成功,这是为什么?

请问大佬,WS_ID的值是OP10,OP23这种,OP后面是数字,我用Concat方法和OrderBy试了一下还是不行,请问OrderBy是不是不能用在此处排序?

额,难怪。 因为字符串排序是按字符编码排序
比如 “1”,“2“,”10“,”11“,”20”
他排序是 "1","10","11","2","20"
所以你需要根据你自己的规则编写 自定义排序比较方法
你可以参考 IComparable接口实现(记不清了,大概是这个接口把)

下面代码是ChartGpt给的,我没进行验证,只是大体上告诉你实现的方向

您可以使用以下代码实现一个StringNumericComparer类来对字符混合数字的字符串进行排序:

using System;
using System.Collections.Generic;
using System.Linq;

public class StringNumericComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        string[] xParts = SplitParts(x);
        string[] yParts = SplitParts(y);

        // Compare parts one by one
        for (int i = 0; i < Math.Min(xParts.Length, yParts.Length); i++)
        {
            int result;
            // If both parts are numeric, compare as integers
            if (int.TryParse(xParts[i], out int xNum) && int.TryParse(yParts[i], out int yNum))
            {
                result = xNum.CompareTo(yNum);
            }
            // Otherwise, compare as strings
            else
            {
                result = xParts[i].CompareTo(yParts[i]);
            }

            // If parts are not equal, return comparison result
            if (result != 0)
            {
                return result;
            }
        }

        // If all parts are equal, compare by length
        return xParts.Length.CompareTo(yParts.Length);
    }

    private string[] SplitParts(string input)
    {
        return input.Split(new[] { " ", "-", "_" }, StringSplitOptions.RemoveEmptyEntries);
    }
}

然后,您可以在LINQ查询中使用此StringNumericComparer类进行排序,例如:

List<string> strings = new List<string> { "abc2", "def1", "xyz10", "abc12", "abc3" };

var sortedStrings = strings.OrderBy(s => s, new StringNumericComparer());

foreach (var str in sortedStrings)
{
    Console.WriteLine(str);
}

这将输出:

abc2
abc3
abc12
def1
xyz10

请注意,该实现假设数字部分不会超过int类型的范围。如果有可能出现较大的数字,请相应地调整类型。

调试下 tmp1 和 tmp2 的内容,ws_id 字段的值
另外
foreach (var item in tmp2)
tmp1.Add(item);
不必要这么写,直接 tmp1.AddRange(tmp2); 即可

在C#中,LINQ查询操作是惰性执行的
调用tmp1.Add(item)将tmp2中的元素添加到tmp1后,tmp1并没有立即进行排序
用Concat方法将tmp1和tmp2合并成一个再用OrderBy排序

【以下回答由 GPT 生成】

问题原因可能是在合并后的集合tmp1上进行了两次排序操作。第一次排序是通过OrderBy(p => p.WS_ID)进行的,第二次排序是通过test.OrderBy(o => o.WS_ID)进行的。

解决方案如下:

  1. 只需要在合并之后对tmp1进行一次排序,不需要再对test进行排序。可以将以下代码
var test = tmp1.ToList();
var tmp = test.OrderBy(o => o.WS_ID).ToList();

简化为

var tmp = tmp1.OrderBy(o => o.WS_ID).ToList();
  1. 如果问题还没有解决,可能是OrderBy排序操作没有生效。可以尝试使用OrderByDescending方法进行降序排序,即将代码修改为
var tmp1 = db.GetList<T_RECORD>(o => o.VALID_FLAG == true && o.ASSEMBLY_CODE.Equals(selectedSn))
            .OrderByDescending(p => p.WS_ID)
            .Select(f => new WsRepaired() { WS_ID = f.WS_ID, WORKPIECE_STATUS = f.WORKPIECE_STATUS.GetValueOrDefault(), ID = f.ID })
            .ToList();

var tmp2 = db.GetList<T_RECORD_VISION>(o => o.VALID_FLAG == true && o.ASSEMBLY_CODE.Equals(selectedSn))
            .OrderByDescending(p => p.WS_ID)
            .Select(f => new WsRepaired() { WS_ID = f.WS_ID, WORKPIECE_STATUS = f.WORKPIECE_STATUS.GetValueOrDefault(), ID = f.ID })
            .ToList();

foreach (var item in tmp2)
{
    tmp1.Add(item);
}

var tmp = tmp1.OrderBy(o => o.WS_ID).ToList();
  1. 如果问题还没有解决,可能是获取数据的方式不正确。可以在获取数据之后使用ToList方法将查询结果转换为列表,避免延迟加载导致的排序问题。修改之后的代码应为:
var tmp1 = db.GetList<T_RECORD>(o => o.VALID_FLAG == true && o.ASSEMBLY_CODE.Equals(selectedSn))
            .OrderBy(p => p.WS_ID)
            .Select(f => new WsRepaired() { WS_ID = f.WS_ID, WORKPIECE_STATUS = f.WORKPIECE_STATUS.GetValueOrDefault(), ID = f.ID })
            .ToList();

var tmp2 = db.GetList<T_RECORD_VISION>(o => o.VALID_FLAG == true && o.ASSEMBLY_CODE.Equals(selectedSn))
            .OrderBy(p => p.WS_ID)
            .Select(f => new WsRepaired() { WS_ID = f.WS_ID, WORKPIECE_STATUS = f.WORKPIECE_STATUS.GetValueOrDefault(), ID = f.ID })
            .ToList();

foreach (var item in tmp2)
{
    tmp1.Add(item);
}

var tmp = tmp1.OrderBy(o => o.WS_ID).ToList();

如果以上解决方案仍然不能解决问题,请提供更多相关代码和错误信息以供进一步分析。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^