Ситуация: для тестирования в проекте используется NUnit + NDbUnit для тестирования работы с базой. Проект работал на MS SQL Server и все было прекрасно. Потом встала задача переделать все на MySQL, что и было сделано, но возникла проблема: NDbUnit с MySQL не дружит. Тоесть NDbUnit поддеживает только SQL Server и OLE DB базы. Ну казалось бы - OLE DB поддерживает, так и используем OLE DB provider для MySQL! Но не тут то было... Сначала встала проблемма, что официального провайдера нет. Нашел тот, что нашел: [
sourceforge.net]. Но и с ним не заработало (кстати, позже нашел еще один: [
cherrycitysoftware.com] Его не пробовал, он 10$ стоит, хотя и бесплатно можно использовать, но с морокой). Погуглил получше и нашел решение [
forums.microsoft.com], хотя и не очень красивое:
- Идем в "Панель Управления" - "Администрирование" - "Источники данных (ODBC)". Там нужно добавить "Системный DSN" для MySQL базы к которой мы хотим приконнектиться, при этом в качестве драйвера выбираем MySQL ODBC 3.51 (можно скачать с оффициального сайта [dev.mysql.com]). В настройках драйвера выставляем все, что положено (кстати, сюда мы еще вернемся), DataSource Name я дал такое же, как у базы.
- Потом при создании Connection String в Visual Studio для Datasource выбираем ".Net Framework Data Provider for OLE DB"
- Для OLE DB Provider используем MSDataShape
- Для "Server or filename" используем DataSource Name, которое дали на шаге 2.
- Жмем "Test Connection" и радуемся.
Но не долго. Хотя MySQL через OLE DB мы к NDbUnit'у прикрутили, он все равно работает неправильно, т.к. внутри себя геренирует неправильные CRUD (Create Read Update Delete) SQL запросы. К счастью, NDbUnit OpenSource'ный, и как мне сказали "Если очень хочется, но нельзя - все возможно". Подсоединяем к проекту исходники NDbUnit.Core, ставим точку останова на той строке, в которой возникает ошибка в тесте (берем из NUnit'а). Ctrl+Alt+P и присоединяемся к процессу NUnit'a. Запускаем тест, попадаем в Visual Studio, по F11 идем вглубь NUnit'a и находим багу - откуда-то берется еще одна колонка с пустым ( "" ) именем, которая добавляется в запрос. С какой радости, мне выяснить не удалось - ставлю заплатку (проверяем, что имя колонки не является пустой строкой - точно ничего не испортит). Ура! Почти заработало: теперь вываливается на строке запроса к полю базы с именем "Version". Ну да - зарезервированное слово в MySQL. Надо писать так: `Version`. Ну, это решается совсем просто: ставим QuotePrefix и QuoteSuffix у OleDbCommandBuilder'a равными "`" . Казалось бы все. Не совсем: у нашей базы сложные связи друг сдругом, которые надо отключить на время тестов (для MS SQL использовалась недокументированная хранимая процедура "sp_msforeachtable" чтобы пройтись по всем таблицам и выполнить "ALTER TABLE ? NOCHECK CONSTRAINT all", для MySQL этот запрос не подходит). У MySQL же есть
"SET FOREIGN_KEY_CHECKS = 0" но работает это только на session. А они открываются опять же где? Внутри NDbUnit'a! И до них не добраться. НО! Помните я в пункте 1) выше говорил что мы еще вернемся к настройкам драйвера? Там есть замечательное поле, навроде "set initial sql statement" (Точного названия не помню - нет под рукой). Вот туда и пишем "SET FOREIGN_KEY_CHECKS = 0". Теперь все нормально наконец-то.
Это решение хоть и работает, но вызывает у меня не лучшие эмоции - добавление источника данных ODBC, через десятые руки работа с базой, внесение изменений в исходники NDbUnit'a... Должен быть другой способ, которого я не нашел. Если кто знает - подскажите в какую сторону смотреть.