Сортировка таблицы данных на основе ascii (или unicode) кода символов

#c# #sorting #datatable #dataset #cultureinfo

#c# #сортировка #таблица данных #набор данных #cultureinfo

Вопрос:

У меня есть таблица данных с данными в столбце string. Значения: «1» «{» «2»

Когда я выбираю данные из сортировки данных по столбцу, я хотел бы получить значения в виде: «1» «2» «{»

но вместо этого я получаю значения в виде: «{» «1» «2»

Если бы мне нужно было сделать это в sql server, я бы использовал сопоставление «Latin1_general_bin». Мне нужно такое же поведение в DataTable.

Вот мой тест:

  [Test]
    public void TestDataTable()
    {
        var dt = new DataTable();
        dt.Columns.Add("a", typeof(string));
        dt.Rows.Add("1");
        dt.Rows.Add("{");
        dt.Rows.Add("2");
        int i = 0;
        foreach (var val in dt.Select("", "a"))
        {
            Assert.AreEqual(new string[] {"1", "2", "{"}[i  ],val["a"]);
        }
    }
 

Ответ №1:

Лучшее решение, которое я могу придумать на данный момент, — это установка частного поля _compareFlags с использованием отражения. Я знаю, я ненавижу рефлексию за это, и она может перестать работать в какое-то неизвестное время, но у меня есть много модульных тестов для этого, поэтому я надеюсь, что я не буду сожалеть об этом.

Любое лучшее решение приветствуется, я думал о создании собственной информации о культуре, но не смог ее просмотреть (открыт для предложений по этому пути).

Вот что я сделал с отражением:

  [Test]
    public void TestDataTable()
    {
        var dt = new DataTable();
        var f = typeof (DataTable).GetField("_compareFlags",
                                            System.Reflection.BindingFlags.NonPublic |
                                            System.Reflection.BindingFlags.Instance);

        var v = (System.Globalization.CompareOptions) f.GetValue(dt);
        f.SetValue(dt,  CompareOptions.OrdinalIgnoreCase);



        dt.Columns.Add("a", typeof(string));
        dt.Rows.Add("1");
        dt.Rows.Add("{");
        dt.Rows.Add("2");
        int i = 0;
        foreach (var val in dt.Select("", "a"))
        {
            Assert.AreEqual(new string[] {"1", "2", "{"}[i  ],val["a"]);
        }
    }
 

Комментарии:

1. для чего используется var v = …. ?

2. Вероятно, бесполезно. Я создал этот пример давным-давно (10 лет назад) 🙂 Вероятно, я использовал v, чтобы просмотреть существующее значение, прежде чем установить для него другое значение

3. Вот о чем я думал. Я удалил его, и он все еще работает должным образом. Tks

Ответ №2:

Вы можете превратить таблицу данных в перечислимую, а затем использовать OrderBy . Затем используйте Enumerable .AsDataView().Таблица.

Может быть немного многовато, но это должно сработать.

Твое здоровье, Лиор :).