Em um script T-SQL, usando uma string de conexão como esta:
Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=C:\Temp\ContextTest.mdf;Initial Catalog=ContextTest;Integrated Security=True
... EU ...
- criar um banco de dados SQL Server LocalDB
- crie um login e adicione um usuário ao banco de dados que criei
- Eu não adiciono nenhuma função de banco de dados ao usuário.
- Eu crio uma tabela e concedo direitos SELECT, INSERT, UPDATE, DELETE, REFERENCE ao usuário
O script se parece com isso:
CREATE LOGIN [U] WITH PASSWORD = '***'
CREATE USER [U] FROM LOGIN [U]
CREATE TABLE [U].[TestEntities]
( Id INT PRIMARY KEY IDENTITY
, Name NVARCHAR(100) NOT NULL UNIQUE
)
GRANT INSERT, DELETE, SELECT, REFERENCES, UPDATE ON [U].[TestEntities] TO [U];
Em seguida, estou usando o SSMS para inspecionar tudo, usando as credenciais que acabei de criar .
Quando me conecto no SSMS usando o usuário recém-criado, posso consultar facilmente a [U].[TestEntities]
tabela usando uma consulta como esta:
SELECT COUNT(*) FROM U.TestEntities
Então, se eu fizer o mesmo em .NET, recebo uma mensagem de erro alegando que eu exigiria direitos CREATE DATABASE:
using namespace System.Data.SqlClient
try {
$con = [SqlConnection]::new('Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=C:\Temp\ContextTest.mdf;Initial Catalog=ContextTest;User ID=U;Password=***')
$cmd = $con.CreateCommand()
$cmd.CommandText = 'SELECT COUNT(*)
FROM [U_MCL].[TestEntities] AS [t]'
$con.Open()
$cmd.ExecuteScalar()
} finally {
$con.Dispose()
}
MethodInvocationException: C:\Temp\Test.ps1:9:2
Line |
9 | $con.Open()
| ~~~~~~~~~~~
| Exception calling "Open" with "0" argument(s): "CREATE DATABASE permission denied in database 'master'. Cannot attach the file
| 'C:\Temp\ContextTest.mdf' as database 'ContextTest'."
o que estou perdendo?
Se eu li sua pergunta corretamente, quando você está fazendo isso no SSMS, você está criando o banco de dados no contexto da sua conta (usando segurança integrada), depois de criar o banco de dados, você está se conectando com as credenciais limitadas para consultar o banco de dados. Isso funciona bem porque sua conta tem permissão para criar bancos de dados, mas a credencial limitada não.
Quando você está se conectando com C#, você está fazendo isso com as credenciais limitadas e passando AttachDbFilename que está fazendo com que o SQL Express tente criar um novo banco de dados nesse contexto, mas as credenciais limitadas não têm permissão para criar/anexar um banco de dados como sua conta, portanto, ele falha. Se você já criou o banco de dados, não precisa especificar AttachDbFilename em sua cadeia de conexão C#, basta conectar como está fazendo pela segunda vez no SSMS.
AttachDbFilename não é a maneira ideal de fazer isso, então também valeria a pena ler esta postagem no blog de Aaron Bertrand para obter mais detalhes sobre como abordar isso melhor.