Ответ 1
Это описанное здесь.
Коллажи Windows (например, Latin1_General_CI_AS
) используют правила сортировки типа Unicode. SQL Collations нет.
Это приводит к тому, что символ дефиса обрабатывается по-разному между ними.
В тестовом примере, который я написал, сравнение строк не работает одинаково между SQL Server/.NET CLR.
Этот код С#:
string lesser = "SR2-A1-10-90";
string greater = "SR2-A1-100-10";
Debug.WriteLine(string.Compare("A","B"));
Debug.WriteLine(string.Compare(lesser, greater));
Будет выводиться:
-1
1
Этот код SQL Server:
declare @lesser varchar(20);
declare @greater varchar(20);
set @lesser = 'SR2-A1-10-90';
set @greater = 'SR2-A1-100-10';
IF @lesser < @greater
SELECT 'Less Than';
ELSE
SELECT 'Greater than';
Будет выводиться:
Less Than
Почему разница?
Это описанное здесь.
Коллажи Windows (например, Latin1_General_CI_AS
) используют правила сортировки типа Unicode. SQL Collations нет.
Это приводит к тому, что символ дефиса обрабатывается по-разному между ними.
В ответ на gbn вы можете заставить их вести себя одинаково с помощью CompareOptions.StringSort в С# (или с помощью StringComparison.Ordinal). Это рассматривает символы как встречающиеся перед буквенно-цифровыми символами, поэтому "-" < "0".
Однако Unicode vs ASCII ничего не объясняет, так как шестнадцатеричные коды кодовой страницы ASCII переводятся до кодовой страницы Unicode: "-" - 002D (45), а "0" - 0030 (48).
Что происходит, так это то, что .NET использует по умолчанию "лингвистическую" сортировку, основанную на порядковом упорядочении и весе, применяемом к различным символам указанной или текущей культурой. Этот лингвистический алгоритм позволяет, например, "резюме" (пишется с акцентами) появляться сразу после "возобновления" (записанного без акцентов) в отсортированном списке слов, так как "é" получает дробный порядок сразу после "e" и задолго до "f". Это также позволяет тесно взаимодействовать "сотрудничество" и "сотрудничество", поскольку символу штриха присваивается низкий "вес"; это имеет значение только как абсолютные окончательные тай-брейки при сортировке слов типа "бит", "бит" и "бит-сдвиг" (которые появятся в этом порядке).
Так называемая порядковая сортировка (строго согласно значениям Юникода, с или без учета нечувствительности к регистру) будет давать очень разные и иногда нелогичные результаты, поскольку варианты букв обычно появляются после основного неаполяризованного латинского алфавита в ординалах ASCII/Unicode, тогда как перед ним появляются символы. Например, "é" приходит после "z", и поэтому слова "резюме" , "канифоль", "рубль", "резюме" будут сортироваться в этом порядке. "Бит", "Бит-сдвиг", "Битер", "Биты" будут сортироваться в этом порядке, поскольку сначала будет апостроф, затем тире, затем буквой "е", затем буквой "с". Ни один из них не кажется логичным с точки зрения "естественного языка".
Более тонкие точки UTF-xx (С#) и UCS-2 (SQL Server) довольно сложны.
Edit:
Я отправил слишком скоро
Я получаю "Больше" на SQL Server 2008 с помощью сопоставления Latin1_General_CI_AS
Изменить 2:
Я также попробую SELECT ASCII(...)
на тире. Например, если фрагмент SQL когда-либо был в документе Word, то - (150) не является - (45), который я скопировал в SQL Server для проверки моего браузера из ваших вопросов. См. CP 1252 (= CP1 = SQL Server lingo)
Изменить 3: См. ответ Мартина Смита: 2 сортировки имеют разные порядки сортировки.
Несколько отличных ответов уже на то, почему это происходит, но я уверен, что другие просто хотят знать код С# для итерации коллекции в том же порядке, что и SQL-сервер. Я нашел следующие работы лучше всего. "Ordinal" обходит проблему с дефисом, в то время как "IgnoreCase", по-видимому, отражает и SQL-сервер.
Debug.WriteLine(string.Compare(lesser, greater, StringComparison.OrdinalIgnoreCase));