Подтвердить что ты не робот

Orderby() не правильно упорядочивает числа С#

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

Проблема заключается в том, что версия сохраняется как строка вместо int, и когда я делаю OrderBy (q = > q.Version) в результатах, они возвращаются как

1
10
11
2
3
...

Очевидно, что 2 до 10.

Есть ли способ передать версию как целое или есть простой IComparer? До сих пор я не мог найти ничего существенного.

Я попытался сделать это:

var items = (from r in results
             select r).OrderBy(q => Int32.Parse(q.Version));

Это компилируется, но не работает.

4b9b3361

Ответ 2

Ваша проблема в другом месте, следующие работы:

new[] { "1", "10", "2", "3", "11" }
    .OrderBy(i => int.Parse(i))
    .ToList()
    .ForEach(Console.WriteLine);

Если ваша проблема связана с LINQ to SQL, то, что происходит, CLR пытается создать SQL из вашего LINQ и не понимает int.Parse. Что вы можете сделать, так это сначала получить данные из SQL, а затем заказать его после загрузки всех данных:

var items = (from r in results
             select r)
            .ToList()
            .OrderBy(q => Int32.Parse(q.Version));

Должно это сделать.

Ответ 3

Если вы не можете изменить определение таблицы (так что версия представляет собой числовой тип), и ваш запрос действительно указан в списке (ваш отказ от использования пропусков или принятия или иное сокращение количества результатов), лучший вы можете сделать, это вызвать "ToList" на несортированных результатах, который, когда вы затем примените lambda OrderBY к нему, будет выполняться в вашем коде, а не пытаться сделать это на конце SQL Server (и который должен теперь работать).

Ответ 4

Почему вы сортируете лямбду? Почему бы вам просто не отсортировать запрос?

var query = from r in items
            orderby int.Parse( r )
            select r;

Теперь, когда мы знаем, что вы используете LINQ to SQL, вы можете подумать о создании стандартного SQL-запроса на этом, выполнив что-то вроде:

Select ..., Cast( TextWhichShouldBeIntCol As int ) As IntCol
From ...

Или даже

Select ..., Cast( TextWhichShouldBeIntCol As int ) As IntCol
From ...
Order By Cast( TextWhichShouldBeIntCol As int )

Это будет истекать кровью в ваш LINQ как int (и если вы используете вторую итерацию, заказывайте). Это позволяет избежать необходимости дважды выполнять набор результатов в LINQ (один раз для запроса, один раз для заказа).

Ответ 5

Там есть замечательная часть кода, которая отлично справляется с естественной сортировкой. Его имя AlphanumComparator.

Пример кода:

var ordered = Database.Cars.ToList().OrderBy(c => c.ModelString, new AlphanumComparator());

Обратите внимание, что список должен быть в памяти.

Если вы получаете версию С#, сделайте следующее:

AlphanumComparator : IComparer<string>

и

public int Compare(string x, string y)

Ответ 6

Я сделал тест. У меня есть следующий код.

string[] versions = { "1", "2", "10", "12", "22", "30" };
foreach (var ver in versions.OrderBy(v => v))
{
     Console.WriteLine(ver);
}

Как и ожидалось, результат равен 1, 10, 12, 2, 22, 30 Затем измените versions.OrderBy(v => v)) на versions.OrderBy(v => int.Parse(v))). И он отлично работает: 1, 2, 10, 12, 22, 30

Я думаю, ваша проблема в том, что в вашей строке есть символы nondigit, например '.'. Какое исключение вы получаете?

Ответ 7

попробуйте следующее:

var items = results.(Select(v => v).OrderBy(v => v.PadLeft(4));

который будет работать в Linq2Sql

Ответ 8

Почему вы сортируете, если вам нужна только "самая высокая версия"? Похоже, вы могли бы избежать некоторых накладных расходов, если вы использовали Max().

Кроме того, вам действительно нужно изменить тип столбца на целое.

Ответ 9

var items = (from r in results
         select r).OrderBy(q => Convert.ToInt32(q.Version));

Определенно запустить......

Ответ 10

Похоже, у вас есть текстовое значение вместо числового значения.

Если вам нужно сортировать, вы можете попробовать:

var items = (from r in results
             select r);
return items.OrderBy( v=> Int.Parse(v.Version) );

Ответ 11

var query = from r in items
            let n = int.Parse(r)
            orderby n
            select n;

Ответ 12

var items = (from v in results
                    select v).ToList().OrderBy(x => int.Parse(x.Version));