H2, DBDataAdapter, свойство Locale, имена столбцов и чувствительность к регистру (сопоставление) - PullRequest
2 голосов
/ 17 ноября 2011

Наше приложение использует 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) == (ı)

Ответы [ 2 ]

1 голос
/ 14 декабря 2011

Мы предложили предлагаемое решение использования всех заглавных букв в именах таблиц / столбцов. Даже при том, что это предполагает, что код DataTable выполняет ToUpper() вместо ToLower() для сравнения без учета регистра, казалось маловероятным, что этот код изменит свое поведение (что нарушит весь код, который использует DataTable без учета регистра).

0 голосов
/ 17 ноября 2011

Есть ли у исключения трассировка стека?Не могли бы вы опубликовать это?

Настройка параметров сортировки не поможет, так как параметры сортировки влияют только на данные (значения столбцов), а не на идентификаторы.

Для идентификаторов H2 использует toUpperCase (Locale.ENGLISH), поэтому на него не влияет турецкая проблема (больше; раньше это была проблема, но это было много лет назад).

У меня былоПосмотрите на исходный код H2Sharp, и я не нашел там проблемы (ToUpper / ToLower не используется).Я также не нашел сообщения об ошибке «Столбец ... не принадлежит таблице ...» там или в H2.

...