【问题标题】:Linq ignoring spaces in OrderByLinq忽略OrderBy中的空格
【发布时间】:2020-01-15 20:07:00
【问题描述】:

我正在运行查询以检索郊区列表。当我应用 OrderBy 时(我希望按字母顺序排列)

query.OrderBy(s => s.Name);

我得到以下命令:

MOUNT ADA
MOUNTAIN BAY
MOUNTAIN GATE
MOUNTAIN VIEW
MOUNT ALFRED
MOUNT BEAUTY

似乎空格被忽略并按没有空格的郊区名称排序。 我需要做什么才能正确订购?我认为它们应该按以下顺序排列:

MOUNT ADA
MOUNT ALFRED
MOUNT BEAUTY
MOUNTAIN BAY
MOUNTAIN GATE
MOUNTAIN VIEW

【问题讨论】:

  • 您针对什么运行查询?一个数据库,一个对象的集合,还是别的什么?如果是数据库,则由该列在数据库中的collated 的位置来确定。如果您对该列执行标准SELECT 和ORDER BY,您应该得到相同的响应(因为这是您的查询告诉数据库执行的操作)。你到底在问什么?
  • .OrderBy(m => m.Name, StringComparer.OrdinalIgnoreCase) 这样的订单。但是标准的字符串顺序也应该这样做。
  • 我用默认排序规则尝试了几个不同的引擎(SQL Server、Oracle、MySQL、PostgreSQL)并得到了预期的顺序。我想不出任何可以尝试的排序规则。您确实需要指定您使用的哪个引擎和排序规则。
  • 查询是针对数据库的。是的,就是排序规则
  • @CaptainMorgan:我能够在 PostgreSQL 12.1 上使用 th-x-icu 和 th-TH-x-icu 排序规则重现这种排序顺序(我编写了一个查询 pg_collation 的测试并测试了所有 650 个排序规则的顺序我有)。 Name 列是使用其中一种排序规则意外创建的吗?

标签: c# linq


【解决方案1】:

由于各个字符分组之间的空格,您的数据库设置似乎对排序顺序有影响。如果您在哪里使用字符串方法Replace() 替换这些空格,则结果集可能会得到所需的结果。但是,如果没有具有您特定设置的 PostgreSQL 12.1 数据库,则无法知道这是否会产生所需的结果。

    private static void TestOrderList()
    {
        var list = new List<string>();
        list.Add("MOUNTAIN GATE");
        list.Add("MOUNT ADA");
        list.Add("MOUNTXADA");
        list.Add("MOUNTAIN BAY APP TOAST");
        list.Add("MOUNTAIN BAY APP ATOAST");
        list.Add("MOUNTAIN BAY APPA");
        list.Add("MOUNTAIN BAY");
        list.Add("MOUNT ALFRED");
        list.Add("MOUNTAIN VIEW");
        list.Add("MOUNT BEAUTY");

        var q = list.AsEnumerable().OrderBy(r => r.Replace("~", ""));
        q.ToList().ForEach(s => Console.WriteLine(s));
    }

免责声明:这与其说是一个解决方案,不如说是一个测试用例。我选择了 Tilda,因为它对 ASCII 字符的排序顺序很低。

【讨论】:

    【解决方案2】:

    我没有改变任何逻辑,但是一个简单的迭代给了我预期的结果。

    public class LinqOrderingForWords
    {
        IList<string> _places;
    
        public LinqOrderingForWords()
        {
            _places = new List<string> { "MOUNT ADA", "MOUNTAIN BAY", "MOUNT BEAUTY", "MOUNTAIN VIEW", "MOUNTAIN GATE", "MOUNT ALFRED", "MOUNT ADA ONE" };
        }
    
        public void OrderPlaces()
        {
            var sorted = _places.OrderBy(s => s);
            sorted.ToList().ForEach(s => Console.WriteLine(s));
        }
    }
    

    请参阅 dotnet fiddle here。

    这是您希望看到的吗?

    【讨论】:

    • 你能重现错误的结果吗?这将是必要的证明,这是一个解决方案。
    • 我没有得到它来重现错误的输出。它的 linq 功能我碰巧看到了正确的顺序。我使用模型将名称与另一个道具作为 Uid(仅用于提供最接近的匹配)。
    • 一个适当的复制将涉及在 PostgreSQL 服务器上执行。
    • 那不行。 OP 正在使用 PostgreSQL。我无法在我的 12.1 安装中重现它,因为我什至没有“en_US.UTF-8”排序规则
    • 是的,这很重要。关键是 OP 得到的错误顺序在服务器上排序,因为 .OrderBy() 在查询中被转换为 ORDER BY。所以为了重现它,你必须使用相同的服务器和排序规则。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多