Наше приложение использует H2Sharp для доступа к базе данных H2 из C # (Framework v4). H2Sharp наследует DBDataAdapter и реализует IDbDataAdapter. Таким образом, то, о чем я спрашиваю, скорее всего, относится к SqlDataAdapter, но я хотел уточнить детали среды.
Недавно мы заметили проблему с доступом к одной и той же базе данных на разных компьютерах. Мы наблюдали, что следующий код иногда работает, иногда выдает ошибку:
DataRow row;
// Fill the row
String s = row["id"];
Ошибка «Идентификатор столбца не принадлежит таблице Abcde».
Приложение работает на компьютере под управлением Win7 64-bit Visual Studio 2010 со всеми исправлениями. Тот же двоичный файл и база данных, скопированная на аналогичный компьютер, выдают эту ошибку. Интересно, что код работает нормально, если строка меняется на
String s = row["ID"];
DataTable
имеет свойство CaseSensitive, установленное на false
, поэтому изначально мы не могли понять, что происходит.
Оказывается, что DataTable
имеет свойство «Locale» и по умолчанию имеет локаль зарегистрированного пользователя (как установлено на вкладке «Format» в настройках панели управления «Region and Language» в Windows 7) , На машинах, на которых это не работает, языковой стандарт пользователя установлен на турецкий, и мы наблюдаем случай «турецкой проблемы I» (*).
Теперь я понимаю природу проблемы, я пытаюсь понять, какие варианты у меня есть, чтобы ее решить. Сначала я подумал о том, можно ли сравнивать имена столбцов и т. Д. В инвариантной культуре, но сами данные сравниваются в данной локали. H2 документация не очень ясно говорит об этом, но, как написано, похоже, что вся база данных управляется одним основным параметром. Кроме того, SELECT * FROM INFORMATION_SCHEMA.COLLATIONS
не возвращает Unicode, поэтому эта опция не представляется возможной.
Кроме того, Документация DataTable также предлагает использовать локаль "для сравнения строк в таблице", поэтому, похоже, нет возможности указать другое поведение для имен столбцов / таблиц по сравнению с пользователем данные.
Я нашел этот пост , в котором упоминается эта проблема, и было принято решение использовать символ «I» вместо «i» в именах таблиц / столбцов. Тем не менее, я думаю, что это решение предполагает, что код выполняет ToUpper () вместо ToLower () перед сравнением строк, поэтому он может быть поврежден, если код DataTable
будет изменен в будущем.
В этом посте также предлагается решение для установки параметров сервера SQL на UTF-8. Это выглядит как более жизнеспособное решение. Тем не менее, я не смог найти способ сделать это для базы данных H2 (оба из-за того, что настройки, похоже, влияют на всю базу данных, а опция UNICODE отсутствует).
Я ценю любой вклад / помощь / руководство.
(*) Турецкий I проблема: На турецком, ToUpper (i) == İ, ToLower (I) == (ı)