Я пишу приложение для своей компании и в настоящее время работаю над функциональностью поиска. Когда пользователь ищет объект, я хочу отобразить последнюю версию (который хранится в базе данных).
Проблема, версия хранится как строка вместо интервала, и когда я делаю OrderBy (q => q. Версия) на результатах, они возвращаются как
1
10
11
2
3
...
Очевидно, 2 прибывает прежде 10.
Существует ли способ для меня снять версию в качестве целого числа или там существует ли простой IComparer? Я ничто не мог найти существенным к настоящему времени.
Я пытался делать это:
var items = (from r in results
select r).OrderBy(q => Int32.Parse(q.Version));
Это компилирует, но не работает.
Int32.Parse не поддерживается транслятором LinqToSql. Convert.ToInt32 поддерживается.
var items = (from v in results
select v).ToList().OrderBy(x => int.Parse(x.Version));
попробуйте следующее:
var items = results.(Select(v => v).OrderBy(v => v.PadLeft(4));
это будет работать в Linq2Sql
Если вы вы не можете изменить определение вашей таблицы (так что версия является числовым типом), и ваш запрос действительно соответствует указанному (вы не используете skip, take или иным образом уменьшаете количество результатов), лучшее, что вы можете сделать, это позвонить «ToList» для несортированных результатов, который, когда вы затем примените к нему лямбда-выражение OrderBY, будет иметь место в вашем коде, а не пытаться сделать это на стороне SQL Server (и что теперь должно работать).
Ваша проблема в другом месте, работает следующее:
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));
Должен сделать это.
Сделал тест. У меня есть следующий код.
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
Затем изменим версий.OrderBy (v => v))
на версий.OrderBy (v => int.Parse (v)))
. И он отлично работает: 1, 2, 10, 12, 22, 30
Я думаю, ваша проблема в том, что в вашей строке есть нецифровые символы, такие как '.'. Какого рода исключение вы получаете?
Похоже, что у вас есть текстовое значение вместо числового.
Если вам нужно отсортировать, вы можете попробовать:
var items = (from r in results
select r);
return items.OrderBy( v=> Int.Parse(v.Version) );
var query = from r in items
let n = int.Parse(r)
orderby n
select n;
Зачем вы сортируете, если вам нужна только «самая высокая версия»? Похоже, что вы могли бы избежать некоторых накладных расходов, если бы использовали Max().
Кроме того, вы действительно должны изменить тип столбца на целое число.
Почему вы выполняете сортировку с помощью лямбда-выражения? Почему бы вам просто не отсортировать запрос?
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 )
That будет истекать кровью в ваш LINQ как int (и если вы используете вторую итерацию, будьте заказаны). Это позволяет избежать необходимости дважды просматривать набор результатов в LINQ (один раз для запроса, один раз для заказа).