2013-06-20 4 views
1

Я пытаюсь создать базу данных, но после ее создания я не могу подключиться к ней.C# создание базы данных программно с SMO

Сервер Microsoft SQL Server 2008 и с использованием .Net 4.5. Мы создаем базу данных с SMO, но мы обычно используем Dapper для подключения и запроса базы данных.

Это код, который я до сих пор, что работает:

System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(connectionString); 

Microsoft.SqlServer.Management.Smo.Server srv = new Microsoft.SqlServer.Management.Smo.Server(new Microsoft.SqlServer.Management.Common.ServerConnection(con)); 

var database = new Microsoft.SqlServer.Management.Smo.Database(srv, dbName); 

database.Create(false); 

database.Roles["db_datareader"].AddMember(???); 
database.Roles["db_datawriter"].AddMember(???); 
database.Roles["db_backupoperator"].AddMember(???); 

srv.Refresh(); 

Noce ???? Я попытался

System.Environment.UserDomainName + "\\" + System.Environment.UserName 

и

System.Environment.UserName 

но оказалась неудачной (обновление) с ошибкой Add member failed for DatabaseRole 'db_datareader'. с обоими значениями.

Проблема в том, что когда я создаю базу данных, я не могу с ней поработать по какой-либо причине (используя Dapper) из той же программы. (update) Я получаю сообщение об ошибке: Cannot open database \"<database_name>\" requested by the login. The login failed.\r\nLogin failed for user '<domain>\\<username>' (где <database_name> - это имя базы данных, <domain> мой домен входа и <username> мой вход в систему Windows).

Я что-то не хватает? Правильно ли я делаю? Я пробовал искать в Интернете, но, похоже, никто не создает базу данных таким образом. Методы есть, он должен работать, нет?

** Update **

Если я комментирую database.Roles["..."].AddMember(...) строки, и добавить точку останова на srv.Refresh(), возобновив программу оттуда решает все.

Почему точка останова решает все? Я не могу просто разбить программу на производстве ... и не прерывать программу при создании базы данных каждый раз.

+0

Вы хотите сказать, что если вы создаете базу данных с SMO, вы можете * никогда не подключаться к ней с помощью Dapper? Можете ли вы подключиться к * любым * базам данных с Dapper? – RBarryYoung

+0

Когда вы пытаетесь добавить участника в роль, вы говорите «сбой», но каково фактическое сообщение об ошибке? Вы распечатали строки, которые вы проходите, чтобы узнать, являются ли они такими, какими вы считаете? – RBarryYoung

+0

@RBarryYoung, я могу подключиться к Dapper, когда создаю базу данных с помощью MSSMS. Моя проблема заключается в том, что я процедурно создаю ее с SMO. –

ответ

1

Похоже, проблема подключения Dapper связана с тем, что SQL Server выполняет некоторые операции SMO ​​асинхронно. По всей вероятности, новая база данных не готова к другим пользователям/соединениям немедленно, но для подготовки SQL Server требуется некоторое небольшое время. В «человеческом времени» (в SSMS или в точке останова) это не заметно, но «время программирования» слишком быстро, поэтому вам, вероятно, придется сделать паузу.

Это может также проблема с этой ролью AddMember, но есть целый ряд вещей, которые могли бы быть неправильно здесь, и мы не имеем достаточно информации, чтобы сказать. (В частности, делает AddMember работы позже? И строка передается правильно или нет?)

+0

Я попытался поставить текущую нить на 1 секунду (время * * * в терминах компьютера), но это не имело никакого значения. Выполняет ли точка останова что-то особенное, что я могу сделать программно и решить проблему? –

+0

@YanickRochon Вы тоже прокомментировали 'AddMember'? Кроме того, попробуйте добавить 'Application.DoEvents' – RBarryYoung

+0

Я прокомментировал' AddMember'. 'Application.DoEvents()' тоже не работает. Мне удалось каким-то образом заставить его работать, вызвав «database.SetOnline();» и «database.BrokerEnabled = true;» **, затем ** спящий 3 секунды в текущем потоке. Это странно, но это работает. Хотя мне интересно, действительно ли это путь. (BTW: Я не работаю иначе.) –

0

Это происходит потому, что вы создали пользователя, но не логина для этого пользователя. Хотя я не знаю точного синтаксиса, вам нужно будет создать Login. Вы хотите установить его LoginType на LoginType.WindowsUser. Кроме того, вам, вероятно, нужно будет установить WindowsLoginAccessType на WindowsLoginAccessType.Grant, и вам нужно будет установить Credential, построив один из них, возможно, NetworkCredential с нужным именем пользователя.

Чтобы поместить визуальный на этом, Login находится под Security узел для Server в Management Studio, тогда как User находится под Security узел для Database. Оба должны существовать для доступа к SQL Server.

+0

Я читал это в других местах, но как вы это реализуете в C#? Можете ли вы привести пример? Кроме того, я * старался выполнить 'CREATE LOGIN' и' CREATE USER', но я получил странные ошибки, говорящие, что предоставленный пользователь существует под другим логином ... или какой-то другой странной вещи. –