Динамический Linq: Как указать тип StringComparison? - PullRequest
2 голосов
/ 06 декабря 2010

Я работаю над некоторой пользовательской фильтрацией и сортировкой набора данных, основанной на наборе полей сортировки, отправленных из браузера клиента, и использую Dynamic Linq для достижения (большей части) желаемого эффекта.Я сталкиваюсь с проблемой, когда пытаюсь отсортировать по столбцу типа String, который содержит как традиционные строки, так и числа, хранящиеся в виде строк.Похоже, я не могу передать значение перечисления StringComparison или указать параметр IComparer для функции заказа Dynamic Linq.

Мой код сортировки выглядит так:

myList.AsQueryable().OrderBy("StringColWithNums ASC")

Я заканчиваюс:

1
10
100
11
12
2
20

вместо:

1
2
10
11
12
20
100

У кого-нибудь есть опыт, делающий что-то подобное?

Ответы [ 4 ]

1 голос
/ 06 декабря 2010
myList.AsQueryable().Sort((r, s) => int.Parse(r).CompareTo(int.Parse(s)));

потребует некоторой настройки, если это объекты, просто используйте int.Parse(r.StringColWithNums) или любое другое поле.

Упс, извините, не прочитал все ОП, чтобы увидеть, что на нем тоже есть буквы, и вам нужен динамический linq, редактирование

EDIT

Я не знаю, что вы сможете сделать это, используя Dynamic linq и передав IComparer. Возможно, вы сможете сделать это после получения результатов (то есть, как я изначально писал, с изменениями). Прокомментируйте, если вы хотите продолжить эту строку.

0 голосов
/ 08 декабря 2010

Кажется, что это не то, что может быть сделано из коробки с Dynamic Linq, по крайней мере, в .NET 2.0 / 3.5. В итоге я изменил исходный код Dynamic Linq, чтобы выполнить то, что мне было нужно.

0 голосов
/ 07 декабря 2010

Вы можете решить эту проблему, написав новую строку сравнения

 class AlphaNumericComparer : IComparer<string>
        {
            public int Compare(string x, string y)
            {
                // if both values are integers then do int comparision
                int xValue, yValue;
                if (int.TryParse(x, out xValue) && int.TryParse(y, out yValue))
                    return xValue.CompareTo(yValue);

                return x.CompareTo(y); // else do string comparison
            }
        }

Тогда вы можете использовать компаратор в таких методах, как OrderBy и Sort

var sorted = lst.OrderBy(s => s, new AlphaNumericComparer());

lst.Sort(new AlphaNumericComparer());

Это даст вам желаемый результат. Если нет, то просто настройте компаратор.

0 голосов
/ 06 декабря 2010

Это фундаментальная проблема при попытке выполнить числовое сравнение в сравнении строк. Я бы сделал это несколькими способами:

  • При загрузке списка ставьте префикс числа с количеством нулей, которое будет сопровождать максимальный размер строки, т.е. String.Format("000000", number). Это будет работать только в том случае, если вы в основном заботитесь о сортировке, а не о появлении результатов - даже тогда вы можете преобразовать «000010» обратно в число и вызвать метод ToString (), чтобы снова отобразить число без начальных нулей. 1006 *

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

...