Ответ 1
Int32.Parse не поддерживается переводчиком LinqToSql. Поддерживается Convert.ToInt32.
Я пишу приложение для своей компании и сейчас работаю над функцией поиска. Когда пользователь ищет элемент, я хочу отобразить самую высокую версию (которая хранится в базе данных).
Проблема заключается в том, что версия сохраняется как строка вместо 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));
Это компилируется, но не работает.
Int32.Parse не поддерживается переводчиком LinqToSql. Поддерживается Convert.ToInt32.
Ваша проблема в другом месте, следующие работы:
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));
Должно это сделать.
Если вы не можете изменить определение таблицы (так что версия представляет собой числовой тип), и ваш запрос действительно указан в списке (ваш отказ от использования пропусков или принятия или иное сокращение количества результатов), лучший вы можете сделать, это вызвать "ToList" на несортированных результатах, который, когда вы затем примените lambda OrderBY к нему, будет выполняться в вашем коде, а не пытаться сделать это на конце SQL Server (и который должен теперь работать).
Почему вы сортируете лямбду? Почему бы вам просто не отсортировать запрос?
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 (один раз для запроса, один раз для заказа).
Там есть замечательная часть кода, которая отлично справляется с естественной сортировкой. Его имя AlphanumComparator
.
Пример кода:
var ordered = Database.Cars.ToList().OrderBy(c => c.ModelString, new AlphanumComparator());
Обратите внимание, что список должен быть в памяти.
Если вы получаете версию С#, сделайте следующее:
AlphanumComparator : IComparer<string>
и
public int Compare(string x, string y)
Я сделал тест. У меня есть следующий код.
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, например '.'. Какое исключение вы получаете?
попробуйте следующее:
var items = results.(Select(v => v).OrderBy(v => v.PadLeft(4));
который будет работать в Linq2Sql
Почему вы сортируете, если вам нужна только "самая высокая версия"? Похоже, вы могли бы избежать некоторых накладных расходов, если вы использовали Max().
Кроме того, вам действительно нужно изменить тип столбца на целое.
var items = (from r in results
select r).OrderBy(q => Convert.ToInt32(q.Version));
Определенно запустить......
Похоже, у вас есть текстовое значение вместо числового значения.
Если вам нужно сортировать, вы можете попробовать:
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;
var items = (from v in results
select v).ToList().OrderBy(x => int.Parse(x.Version));