2013-06-20 140 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(); 

诺斯的????我曾尝试

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

System.Environment.UserName 

,但它与错误Add member failed for DatabaseRole 'db_datareader'.与这两个值失败(更新)。

问题是,当我创建数据库时,由于某种原因(使用Dapper),我无法将其从同一程序中进行合并。 (更新)我收到错误消息:Cannot open database \"<database_name>\" requested by the login. The login failed.\r\nLogin failed for user '<domain>\\<username>'(其中<database_name>是数据库名称,<domain>我的登录域,和<username>我的Windows登录)。

我错过了什么吗?我做对了吗?我试过在网上搜索,但似乎没有人用这种方式创建数据库。方法在那里,它应该工作,不是?

** 更新 **

如果我评论了database.Roles["..."].AddMember(...)线,我在srv.Refresh()添加一个破发点,程序重启从那里解决一切问题。

为什么断点解决了一切?我不能在生产中破坏程序......也不能每次创建数据库时都破坏程序。

+0

你是说如果你用SMO创建数据库,那么你可以*永远不会*用Dapper连接到它?你能用Dapper连接到*任何*数据库吗? – RBarryYoung

+0

当您尝试将成员添加到角色时,您会说“失败”,但实际的错误消息是什么?你打印出你正在传递的字符串,看看它们是你认为的吗? – RBarryYoung

+0

@RBarryYoung,当我使用MSSMS创建数据库时,我可以连接Dapper。我的问题是当我用SMO程序化地创建一个。 –

回答

1

听起来像Dapper连接问题是SQL Server异步执行一些SMO操作的问题。很有可能,新的数据库不能立即为其他用户/连接做好准备,但SQL Server需要一些时间来准备它。在“人性化”(SSMS或Breakpoint)中,这并不明显,但“程序时间”太快,所以您可能需要暂停一下。

可能也与角色的AddMember的问题,但是也有一些事情,可能是错在这里,我们没有足够的信息来告诉。 (具体而言,确实AddMember工作以后?和正在传递字符串正确与否?)

+0

我试过把当前的线程睡1秒(在计算机的术语中是一个*长*的时间),但它没有区别。断点是否完成了我可以通过编程方式解决问题的任何特殊功能? –

+0

@YanickRochon您是否也评论过“AddMember”调用?另外,尝试添加一个'Application.DoEvents' – RBarryYoung

+0

我评论了'AddMember'。 'Application.DoEvents()'也没有工作。不管怎样,我通过调用'database.SetOnline();'和'database.BrokerEnabled = true; **然后**在当前线程上休眠3秒来管理它。这很奇怪,但它的工作原理。虽然我不知道这是否是真的要走。 (顺便说一句:我没有其他方式工作。) –

0

这是发生,因为你所创建的用户,但该用户没有登录。虽然我不知道确切的语法,但您必须创建Login。您需要将其LoginType设置为LoginType.WindowsUser。此外,您可能需要将WindowsLoginAccessType设置为WindowsLoginAccessType.Grant,并且您需要设置Credential,方法是使用所需的用户名构建一个,可能是NetworkCredential

要穿上这视觉的Login是在Management Studio中ServerSecurity节点下,而User对于DatabaseSecurity节点下。两者都需要存在才能访问SQL Server。

+0

我也读过其他地方,但你如何在C#中实现这一点?你能提供一个例子吗?此外,我*已*尝试执行'CREATE LOGIN'和'CREATE USER',但我得到奇怪的错误,说提供的用户存在于不同的登录名下......或者其他一些奇怪的事情。 –

相关问题