почему строка IndexOf() действует без учета регистра?

Я действительно озадачен этим. Я изучаю LINQ и использую Microsoft Visual C# Express Edition для подключения к базе данных SQL Server, содержащей информацию о моих книгах. Я создал классы LINQ to SQL по мере необходимости. Эта штука явно работает. Все это работает, за исключением того, что я не могу понять, почему, если я ищу «SR» (в верхнем регистре), он находит две записи: «SR-71 Revealed, The Inside Story», как и ожидалось, но он также находит " Faded Sun: Kesrith", где "sr" в нижнем регистре. Я использую метод IndexOf() класса string, который должен выполнять сравнение с учетом регистра, верно? В выходных данных отображается второе название книги, как показано выше, с буквой «sr» в нижнем регистре. Вот соответствующая часть кода:

// normal using directives here
namespace QueryBooksDB {
    class Program {
        static void Main() {
            var urgh = new BooksDataContext();

            Console.WriteLine("Enter a string to search for:");
            string str = Console.ReadLine();

            var list = from book in urgh.Books
                        where book.Title.IndexOf(str) > -1
                        orderby book.Title
                        select new { ID = book.BookId, book.Title, book.Location };

            foreach ( var b in list ) {
                Console.WriteLine(b.Title);
            }
        }
    }
}

person user1013210    schedule 25.10.2011    source источник
comment
SQL Server по умолчанию не чувствителен к регистру.   -  person Marc    schedule 25.10.2011


Ответы (2)


На последнем этапе ваш запрос переводится в sql. В строковых полях SQL-сервера (varchar, nvarchar) регистр не учитывается. Таким образом, select * from tbl where col like '%foo%' будет получать, если значение равно Foo или FOo.

person Oybek    schedule 25.10.2011
comment
Ах, LINQ to SQL, ты такой сумасшедший. - person BoltClock; 25.10.2011
comment
Хорошо спасибо! Поэтому, чтобы убедиться, я должен перепроверить возвращенные заголовки с помощью IndexOf AGAIN, чтобы убедиться, что регистр правильный, прежде чем я выведу их. - person user1013210; 25.10.2011
comment
@ user1013210 или вы измените collation для своей базы данных на тип с учетом регистра. msdn.microsoft.com/en-us/library/ms144260.aspx - person Marc; 25.10.2011

Я думал, что по умолчанию он чувствителен к регистру, но вы всегда можете использовать перегрузку StringComparison, чтобы указать чувствительность к регистру:

test.IndexOf("foo", StringComparison.Ordinal);

StringComparison перечисление:

  1. ТекущаяКультура
  2. CurrentCultureIgnoreCase
  3. ИнвариантКультура
  4. InvariantCultureIgnoreCase
  5. Порядковый номер
  6. OrdinalIgnoreCase
person James Johnson    schedule 25.10.2011
comment
Я не верю, что это поддерживается в L2S. - person Marc; 25.10.2011
comment
Вы можете использовать IndexOf, но не перегрузку? Вы можете это объяснить? - person James Johnson; 25.10.2011
comment
Если бы я был умнее или работал в команде L2S, я бы смог. Мне пришлось просто попробовать, чтобы убедиться, что провайдер L2S отказался от этого, и он это делает. NotSupportedException. - person Marc; 25.10.2011