If I crate a static DB Connection into a C# Web service
This instance of connection is shared on all istance of web service? So, In this way could I have problem some this?
Not allowed to change the 'ConnectionString' property while the
connection (state=Connecting)
I get the instance in this way:
public static OleDbConnection GetDatabaseConnection(string aConnectionString)
{
if (_dbConnection == null)
{
_dbConnection = new OleDbConnection(aConnectionString);
_dbConnection.Open();
}
else
{
_dbConnection.Close();
_dbConnection = new OleDbConnection(aConnectionString);
_dbConnection.Open();
}
Log.Logger.log("Aperta connessione al DB");
return _dbConnection;
}
It is always a bad practice to keep a global connection instance. You should follow the standard pattern: create, open, use, close and destroy.
Working against this will result, sooner or later, in problems.
The Connection Pooling mechanism has been studied just for this.
The Pool will help you to avoid this bad habit to keep an object so expensive like a database connection open for unforeseeable time
public static OleDbConnection GetDatabaseConnection(string aConnectionString)
{
OleDbConnection odb = new OleDbConnection(aConnectionString);
odb.Open();
Log.Logger.log("Aperta connessione al DB");
return odb;
}
then your client code use the using statement to close and destroy the connection
using(OleDbConnection cn = SqlClassHelper.GetDatabaseConnection(constring))
{
// define here your OleDbCommand, OleDbDataReader etc...
// use the objects
} // <- here the closing brace close and destroy the connection
Yes, you will have problems with your code in a multithreaded web service.
Your function GetDatabaseConnection works like a factory, everybody who calls it gets a new instance of connection. You do not need static _dbConnection class member, just make it a local variable:
public static OleDbConnection GetDatabaseConnection(string aConnectionString)
{
OleDbConnection _dbConnection = new OleDbConnection(aConnectionString);
_dbConnection.Open();
Log.Logger.log("Aperta connessione al DB");
return _dbConnection;
}
Related
I am using npgsql to connect to a CockroachDb cluster, in code with each command I want to execute I create a new connection and open it! I wonder if creating a private field variable holding the connection and opening it then closing it is much better than my current approach?
static async Task Task1()
{
using (var conn = new NpgsqlConnection(connString))
{
conn.Open();
new NpgsqlCommand("SQL Query here", conn).ExecuteNonQuery();
conn.Close();
}
}
static async Task Task2()
{
using (var conn = new NpgsqlConnection(connString))
{
conn.Open();
new NpgsqlCommand("SQL Query here", conn).ExecuteNonQuery();
conn.Close();
}
}and so on ....
Not really: although possible, it's a bit of an anti pattern.
NpgsqlConnection inherits from DbConnection. And DbConnection is a general Microsoft abstract class that represents a database connection, which is IDisposable.
So when putting the conn in a using block, you implicitly call Dispose as soon as it goes out of scope. This will close the connection and clean up other stuff. You don't have to separately call Close.
What you could do, is make a general wrapper like
public static async Task NonQueryCommand(string command)
{
using (var conn = new NpgsqlConnection(connString))
{
conn.Open();
using (var cmd = new NpgsqlCommand(command, conn) // Also IDisposable
{
cmd.ExecuteNonQuery();
}
}
}
But you could lose all flexibility that way (the repository pattern can be bad if not used correctly).
Also check the official resources
Today I noticed a snippet of code that looks like the one below:
public class Test
{
SqlConnection connection1 =
new SqlConnection(ConfigurationManager.ConnectionStrings["c1"].ToString());
SqlConnection connection2 =
new SqlConnection(ConfigurationManager.ConnectionStrings["c2"].ToString());
public void Method1()
{
using (connection1)
{
connection1.Open();
using (SqlCommand newSqlCommand = new SqlCommand("text",connection2))
{
// do something
}
}
}
public void Method2()
{
using (connection1)
{
// do something
}
}
}
I am just wondering why would anyone want to open the connection when creating the class and not when calling the corresponding methods inside the class?
EDIT: I should have probably posted the whole code instead. So I do see where they are opening connection1, but then they are instantiating a sqlcommand with a different sql connection (connection2) which has not been opened anywhere. What am I missing here?
Thanks,
This line only initializes a connection object, which can later be used to open a connection to a database server.
SqlConnection connection1 =
new SqlConnection(ConfigurationManager.ConnectionStrings["c1"].ToString());
What I know is that using disposes of an object (and in the case of Connection objects they are automatically closed) after its scope so I wouldn't recommend such usage because it might be problematic with other object types (other than Connection) that can't be used after having their dispose called.
connection1 = new SqlConnection(...) does not really open the connection. It just creates the connection object.
You have to call connection1.Open(); to actually open it. You can do this inside using statement block.
Refer to this MSDN page for more details.
It either
written this way to enforce only single call to a method be performed on the class
unintentionally confusing by throwing ObjectDisposed exception if you call 2 methods
contains connection re-initialization code in blocks you've ommited.
The code is dangerous.
If you call Method1 then Method2 (or visa versa) you will get an error (connection string not initialized).
The error occurs because the using statement will close the connection AND Disposes the object. I double checked what happens when dispose is called...the connection string is cleared (and possibly some other things I didn't notice).
You don't want to re-use a disposed object.
The cost of instantiating a new connection object is insignificant so I would just create the object where needed, maybe with a little factory method to reduce code duplication, so change to something like:-
private static SqlConnection GetSqlConnection()
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["c1"].ToString());
}
private void Method1()
{
using (var conn = GetSqlConnection())
{
conn.Open();
// do stuff...
}
}
private void Method2()
{
using (var conn = GetSqlConnection())
{
conn.Open();
// do other stuff...
}
}
Of course there are many different ways of approaching this problem, this is just one and indeed quite a simplistic one...but it is a good starting point and is safe :-)
I have a class which uses both ADO.NET and LINQ to access a pair of databases on one server. The tables in the DBs are not extensive and so the entity objects are fairly light. I have written the code as best as I, using experience and net articles of course. For example...
http://dotnetperls.com/sqldataadapter
http://www.velocityreviews.com/forums/t71781-set-maximum-pool-size-in-web-config.html
http://msdn.microsoft.com/en-us/library/ms971481#adonetbest_topic5
The server which is running my code is only running my code and is not the same server as the db host. From looking at the connections going to the DB server from the my .NET app server (it's a Windows Service, but I don't want to dwell on that as it seem immaterial right now) the number of connections is around 200, but it should certainly be less than that; It should be around 10 as I have set the Max Pool Size to 10 in the appSettings.config.
Could anyone take a look at my connection code and tell me if I'm doing something which would cause the connections to shoot up, please?
Here is my LINQ DB context creation:
private const string ConnectionKey = "SQL2";
protected static string ConnectionString
{
get
{
return _connectionString = (_connectionString == null) ? ConfigurationManager.ConnectionStrings[ConnectionKey].ConnectionString : _connectionString;
}
}
private static string _connectionString = null;
protected static PricingDBDataContext ContextDB
{
get
{
if (_context == null)
{
_context = new PricingDBDataContext(ConnectionString);
}
return _context;
}
}
private static PricingDBDataContext _context = null;
Here is the ADO.NET side of things:
protected DataSet GetDataSet(bool isSproc, string cmdStr, params object[] args)
{
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
using (SqlCommand cmd = new SqlCommand(cmdStr, conn))
{
cmd.CommandType = isSproc ? CommandType.StoredProcedure : CommandType.Text;
for (int index = 0; index < args.Length; index += 2)
cmd.Parameters.AddWithValue(args[index].ToString(), args[index + 1]);
conn.Open();
DataSet set = FillSet(cmd);
conn.Close();
return set;
}
}
}
private DataSet FillSet(SqlCommand cmd)
{
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet set = new DataSet();
adapter.Fill(set);
return set;
}
Thanks,
Matt.
As a general rule, if you are doing anything explicit with the connection pool, you are probably doing it wrong. The default settings have served me well since the early days of .Net
Here are some things to keep in mind:
ADO will pool connections that have exactly the same connection string
Most ado.net objects implement IDisposable and should be disposed of either explicitly or in a using block. This includes connections, commands, datasets and data readers
Linq 2 SQL and EF data contexts also implement IDisposable and should be disposed
I am building an application with c# and I decided to use the Enterprise Library for the DAL (SQL Server).
I don't remember where, but I had read an article about EntLib which said that the connections are closed automatically.
Is it true?
If not, what is the best approach of managing the connections in the middle layer?
Open and close in each method?
The above is a sample method of how I am using the EntLib
public DataSet ReturnSomething
{
var sqlStr = "select something";
DbCommand cmd = db.GetSqlStringCommand(sqlStr);
db.AddInParameter(cmd, "#param1", SqlDbType.BigInt, hotelID);
db.AddInParameter(cmd, "#param2", SqlDbType.NVarChar, date);
return db.ExecuteDataSet(cmd);
}
Thanks in advance.
the ExecuteDataSet method returns a DataSet object that contains all the data. This gives you your own local copy. The call to ExecuteDataSet opens a connection, populates a DataSet, and closes the connection before returning the result
for more info:
http://msdn.microsoft.com/en-us/library/ff648933.aspx
I think you should have something like a static class used as a Façade which would provide the correct connection for your library subsystems.
public static class SystemFacade {
// Used as a subsystem to which the connections are provided.
private static readonly SystemFactory _systemFactory = new SystemFactory();
public static IList<Customer> GetCustomers() {
using (var connection = OpenConnection(nameOfEntLibNamedConnection))
return _systemFactory.GetCustomers(connection);
}
public static DbConnection OpenConnection(string connectionName) {
var connection =
// Read EntLib config and create a new connection here, and assure
// it is opened before you return it.
if (connection.State == ConnectionState.Closed)
connection.Open();
return connection;
}
}
internal class SystemFactory {
internal IList<Customer> GetCustomers(DbConnection connection) {
// Place code to get customers here.
}
}
And using this code:
public class MyPageClass {
private void DisplayCustomers() {
GridView.DataSource = SystemFacade.GetCustomers();
}
}
In this code sample, you have a static class that provides the functionalities and features of a class library. The Façade class is used to provide the user with all possible action, but you don't want to get a headache with what connection to use, etc. All you want is the list of customers out of the underlying datastore. Then, a call to GetCustomers will do it.
The Façade is an "intelligent" class that knows where to get the information from, so creates the connection accordingly and order the customers from the subsystem factory. The factory does what it is asked for, take the available connection and retrieve the customers without asking any further questions.
Does this help?
Yes, EntLib closes connections for you (actually it releases them back into the connection pool). That is the main reason why we originally started to use EntLib.
However, for all new development we have now gone on to use Entity Framework, we find that much more productive.
Which pattern is better for SqlConnection object? Which is better in performance?
Do you offer any other pattern?
class DataAccess1 : IDisposable
{
private SqlConnection connection;
public DataAccess1(string connectionString)
{
connection = new SqlConnection(connectionString);
}
public void Execute(string query)
{
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = query;
command.CommandType = CommandType.Text;
// ...
command.Connection.Open();
command.ExecuteNonQuery();
command.Connection.Close();
}
}
public void Dispose()
{
connection.Dispose();
}
}
VS
class DataAccess2 : IDisposable
{
private string connectionString;
public DataAccess2(string connectionString)
{
this.connectionString = connectionString;
}
public void Execute(string query)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = connection.CreateCommand();
command.CommandText = query;
command.CommandType = CommandType.Text;
// ...
command.Connection.Open();
command.ExecuteNonQuery();
command.Connection.Close();
}
}
public void Dispose()
{
}
}
There's no real way to answer this question. The short, canonical answer is that the connection should stay alive for the lifetime of your unit of work. Because we have no way of knowing how DataAccess is used (does it exist for the lifetime of your application, or do you instantiate it and dispose it whenever you do something?), it's impossible to give a concrete answer.
That being said, I would recommend the first pattern, but instantiate and dispose of your DataAccess object as needed; don't keep it around longer than necessary.
Suggest going with DataAccess2. It's a personal preference though. Some might even suggest your class be static. It'd be difficult to say that one is more performant than the other. You're on the path of IDisposable, which is great.
I'd be happy to read and maintain both styles shown above in your question.
Consider having your DAL be able to read the connection string from a .config as well, rather than exclusively allowing the value to be passed in the constructor.
public DataAccess2(string connStr)
{
this.connectionString = connStr;
}
public DataAccess2()
{
this.connectionString =
ConfigurationManager.ConnectionStrings["foo"].ConnectionString;
}
Consider wrapping your SqlCommand in a using as well.
using (var conn = new SqlConnection(connectionString))
{
using(var cmd = conn.CreateCommand())
{
}
}
I think it depends on how your DataAccess object is intended to be used, if it's used within a 'using' clause then the connection is guaranteed to be disposed of after it's done.
But in general I prefer the second pattern as the sql connection is created and disposed of within the Execute method so it's less likely to be left open when you forget to dispose of your DataAccess object.
Considering that sql connection can be a scarse resource I think every attempt should be made to ensure that they're not wasted.
The first will result in errors if you make concurrent calls.
The second will ensure you use a clean connection for each command resulting in more connections being made.
I agree with the statements above that it depends on the scenario for use, to get over the problem related to the first I have a wrapper that needs to use such a pattern so I set a field value boolean to show that a command is being executed on the connection already then "queue" the next command for execution.
There will of course be situations where you may prefer to use multiple connections ...