Reputation: 863
I created global static class, and it has a SqlConnection
as in code below:
public class Globals
{
public static SqlConnection SqlDbConn;
public static OpenConnection(String ConnString)
{
SqlDbConn = new SqlConnection(ConnString);
SqlDbConn.Open();
}
}
And then created web service, and it have more one function.
My question is: how can I use the same connection (SqlDbConn
) in all functions in the same time? In other words, there are multi-user calling this web service at the same time, and each function in web service using the same SqlDbConn
, this is true way? If not why ?
Finally, in web service I used this constructor to initial the connection:
public class Service1 : System.Web.Services.WebService
{
private static bool Initialized = false;
static string ConnString= @"Data Source=192.168.1.1\SQLEXPRESS;UID=sa;PWD=0000;Initial Catalog=DBName; MultipleActiveResultSets=true";
public Service1()
{
// This method called each function call
if (!Initialized )
{
Globals.OpenConnection(ConnString);
Initialized = true;
}
}
}
Upvotes: 0
Views: 879
Reputation: 216313
Your code could be very wrong in presence of threads and in any case it is a poor copy of the Connection Pooling infrastructure that already takes care of reusing in an efficient way a physical connection.
However you don't need many changes to have a better approach
public class Globals
{
// Keep global just the connection string
// (albeit you could simply pass it every time)
public static string ConnString {get;set;};
// Change the OpenConnection method to return the SqlConnection created
public static SqlConnection OpenConnection()
{
SqlConnection cnn = new SqlConnection(ConnString);
cnn.Open();
return cnn;
}
}
.....
public class Service1 : System.Web.Services.WebService
{
private static bool Initialized = false;
public Service1()
{
// This method called each function call
if (!Initialized )
{
// Don't hard code the connectionstring details, read it from CONFIG
// See ConfigurationManager class....
string connectionString = ReadConnectionStringFromYourConfigFile()
Globals.ConnString = connectionString;
Initialized = true;
}
}
// An usage example of your Globals
public int GetDatabaseValue()
{
using(SqlConnection cn = Globals.OpenConnection())
{
.....
} // Here the connection will be closed and disposed also in case of exceptions...
}
}
Upvotes: 0
Reputation: 755033
The generally accepted Best Practice for dealing with connections and commands on a "raw" ADO.NET level is to always create those objects as needed, as late as possible, and free them again as soon as possible. ADO.NET already has a very sophisticated connection pooling mechanism built-in - no point in trying to outsmart that well-proven mechanism.
In order to ensure proper disposal of the objects, it is also generally accepted to put them into using(...) { ... }
blocks - something like this:
// define query as a string
string query = "SELECT ..... FROM ... WHERE ......";
// create connection and command in "using" blocks
using (SqlConnection conn = new SqlConnection(-your-connection-string-here-))
using (SqlCommand cmd = new SqlCommand(conn, query))
{
// set up e.g. parameters for your SqlCommand
// open the connection, execute the query, close the connnection again
conn.Open();
// for a SELECT, use ExecuteReader and handle the reader (or use SqlDataAdapter to fill a DataTable)
// for UPDATE, INSERT, DELETE just use a ExecuteNonQuery() to run the command
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
// handle the data from the reader
}
// close reader
rdr.Close();
}
conn.Close();
}
Upvotes: 2
Reputation: 3523
You should create a new SqlConnection
instance on every call to the database and Dispose
it when youre done. SqlConnection has a pooling mechanism that create and reuses connections for you. Handling every call on a single connection object can possibly throw session busy exceptions on async operations
Upvotes: 3