问题
I'm having a weird issue that I can't figure out. I'm trying to write some integration tests around some database code and my unit tests fail with a weird exception. Running the code normally under a console application work just fine.
public static class DatabaseManager
{
public static VerifyServceConnectionResult VerifyServerConnection(Server server)
{
try
{
using (var conn = new SqlConnection(BuildConnectionString(server)))
{
conn.Open();
}
return new VerifyServceConnectionResult { ConnectionSuccessful = true };
}
catch (SqlException ex)
{
return new VerifyServceConnectionResult
{
ConnectionSuccessful = false,
ErrorMessage = ex.Message
};
}
catch (Exception ex)
{
return new VerifyServceConnectionResult
{
ConnectionSuccessful = false,
ErrorMessage = "General Exception: " + ex.Message
};
}
}
private static string BuildConnectionString(Server server)
{
var builder = new SqlConnectionStringBuilder();
builder.DataSource = server.DataSource;
builder.IntegratedSecurity = server.UseIntegratedSecurity;
return builder.ConnectionString;
}
}
as soon as conn.open gets called within the Nunit Test I get an exception "Arithmetic operation resulted in an overflow." Any ideas on why such a simple test would be failing in nunit with such a weird error. Again, the code works just fine outside of the context of the unit test.
Thanks
edit: adding stack trace
at SNIOpenSyncExWrapper(SNI_CLIENT_CONSUMER_INFO* , SNI_ConnWrapper** )
at SNINativeMethodWrapper.SNIOpenSyncEx(ConsumerInfo consumerInfo, String constring, IntPtr& pConn, Byte[] spnBuffer, Byte[] instanceName, Boolean fOverrideCache, Boolean fSync, Int32 timeout, Boolean fParallel)
at System.Data.SqlClient.SNIHandle..ctor(ConsumerInfo myInfo, String serverName, Byte[] spnBuffer, Boolean ignoreSniOpenTimeout, Int32 timeout, Byte[]& instanceName, Boolean flushCache, Boolean fSync, Boolean fParallel)
at System.Data.SqlClient.TdsParserStateObject.CreatePhysicalSNIHandle(String serverName, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Byte[]& instanceName, Byte[] spnBuffer, Boolean flushCache, Boolean async, Boolean fParallel)
at System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean withFailover)
at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover)
at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout)
at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.Open()
at xxx.Database.DatabaseManager.VerifyServerConnection(Server server) in d:\projects\TFS\xxx.visualstudio.com\SnydJK.DatabaseUtility\Database\DatabaseManager.cs:line 17
回答1:
Recently, I experienced an exception with the same call stack.
Enviroment
I was using LocalDB server on Windows 8.1 64-bit (not in domain) with default UAC settings and the user is local admin, Framework v4.0.2 (see why it's important). Sadly, the issue can't be reproduced on other computers with the same enviroment.
Issue description
Found out that the exception occurs in the following conditions:
- There is
Integrated Security
parameter in the connection string which is used to create a new database. - The same process opens a connection to the newly created DB after it got created.
Breaking one of these two conditions allows to get through without exceptions. So omitting the Integrated Security
is the easiest way to go. As an option - don't open connection to the newly created DB in the same process. But just adding a pause after creating a DB wouldn’t help if we’re still working in the scope of one process.
Solution
Chuck out the Integrated Security
parameter in the connection string when have a deal with LocalDB.
General Comments
Integrated Security
is an option, which specifies that Windows account credentials are used for authentication (see details on MSDN and here). Having this option (value True
or SSPI
) is recommended for SQL Servers.
Meanwhile this option doesn’t make any difference for LocalDB servers. Regardless of this setting, LocalDB will still be a user instance, running under the account that started it. Basically, it’ll be as Integrated Security
was set to True
or SSPI
. There is no way in LocalDB to prevent the user from accessing data in their database (e.g. by using SQL authorisation). Once the user has access to the database file, they can spin up their own LocalDB instance and open the database.
Hence all recommendations to specify the Integrated Security
when connecting to LocalDB have no grounds.
来源:https://stackoverflow.com/questions/25836198/cant-open-sqlconnection-within-nunit-test