Cockroach connection best practice? - c#

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

Related

Will supplying a SQLCommand with a new SQLConnection call Dispose on the new SQL Connection? [duplicate]

This question already has answers here:
Dispose object that has been instantiated as method parameter c#
(2 answers)
Closed 3 years ago.
PREAMBLE
I understand that normally most SQL calls run thusly
using(var cnn = new DbConnection("YOURCONNECTIONSTRINGHERE")
{
cnn.Open(); //Open the connection.
using(var cmd = new DbCommand("YourSQL", cnn)
{
cmd.ExecuteScalar; //Or whatever type of execution you want.
}
}
This will properly dispose of both the connection and the command.
My Question: Will this code properly dispose of both objects?
using(var cmd = new SqlCommand("YourSQL", new Connection("YOURCONNECTIONSTRINGHERE"))
{
cmd.ExecuteScalar; //Or whatever type of execution you want.
}
In reality I'm using a method that provides and opens the connection.
public SqlConnection Connection()
{
var product = new SQLConnection("ConnectionString");
product.Open();
return product;
}
So at the end of the day the call looks like this:
using(var cmd = new SqlCommand("YourSQL", Connection())
{
cmd.ExecuteScalar; //Or whatever type of execution you want.
}
I know the SqlCommand object will be disposed of but will the SQLConnection, created within the using parameter declaration, be disposed of? I've tried running some simple unit tests but it seems inconclusive.
Will this code properly dispose of both objects?
using(var cmd = new SqlCommand("YourSQL", new Connection("YOURCONNECTIONSTRINGHERE"))
{
cmd.ExecuteScalar; //Or whatever type of execution you want.
}
The above code does not call Dispose() on the connection. The using block ensures that cmd.Dispose() is called immediately after the execution of the block, but the connection remains open. Since the connection has no object referencing it, it will be eventually closed/disposed by the Garbage Collector.
If you want to dispose the Command and Connection immediately, then try:
using (var con = Connection()) // <-- GetConnection() would be a better name
using (var cmd = new SqlCommand(con)
{
cmd.ExecuteScalar;
}

c# using statement with double IDisposable

I have following statement using using:
using (var reader = data.CreateCommand(sql).ExecuteDataReader())
in this case data is some object which internally holds SqlConnection. CreateCommand(sql) function returns SqlCommand and ExecuteDataReader returns SqlDataReader. Since SqlCommand and SqlDataReader are both IDisposable, will they both be disposed by this use of using statement?
For now I have done it like this:
using (var cmd = data.CreateCommand(sql))
using (var reader = cmd.ExecuteDataReader())
But I would like to know if it's possible to combine them as stated above?
"if it's possible to combine them" - two using are totally fine, because both needs to be disposed.
You can combine them by extracting into method:
void RunWithReader(string sql, Action<SQLDataReader> action)
{
using (var cmd = data.CreateCommand(sql))
using (var reader = cmd.ExecuteDataReader())
action(reader);
}
Then you can use lambda
RunWithReader("whatever command", reader =>
{
... // while(reader.Read() { ... } - this could also be extracted
});
Agree with Matthew Watson's comment. You need to have both of usings statemets.
Here is the related question with additional reasoning. SqlConnection SqlCommand SqlDataReader IDisposable
The way you have presented your code the inner IDisposable (IDbCommand) is not disposed.
You have two choices:
You can put it all in one using like this:
using (IDisposable cmd = data.CreateCommand(), reader = ((IDbCommand)cmd).ExecuteReader())
{
// code here
}
But that is rather cumbersome. The other option is nested using statements:
using (var cmd = data.CreateCommand())
{
using (var reader = cmd.ExecuteReader())
{
// code here
}
}
Other than that you can get a bit complicated and write an extension method to help (sort of) clean it up for you.
public static class Ex
{
public static void Using<T, R>(this T obj, Func<T, R> create, Action<T, R> use) where R : IDisposable
{
using (var d = create(obj))
{
use(obj, d);
}
}
}
Then you can do this:
data.Using(d => d.CreateCommand(), (d, c) => c.Using(c2 => c2.ExecuteReader(), (c3, r) =>
{
// code here
}));
But perhaps that's not much of an improvement.
In General
You should Dispose every class that implements IDisposable.
However, your question is specifically dealing with a scenario where all the resources are all related, which if my understanding is correct, the Garbage Collector will dispose these resources for you automatically.
The Finalize() Method ("Destructors" or "Finalizers")
The Finalize() method makes sure that resources are disposed when
the instance is no longer referenced by the application.
In concert together with the Dispose() method
The Dispose() method will "release all resources used by the component". Which would mean that this code block (taken from MSDN's ExecuteReader Method Example) will properly dispose of all the compenents used by it...
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(queryString, connection);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
// ...
}
}
In this case, when disposing SqlConnection, it will properly
release all resources used by the component. Which means:
SqlCommand
SqlDataReader
** Note: This has always been my understanding...
Refactoring of the above code to the following:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(queryString, connection))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// ...
}
}
}
}
The main advantage of manually disposing of each resource, would be
for a performance gain since we are not processing up to the
Finalize method (which is relatively a more expensive than doing Dispose().
However, that doesn't mean you want to Dispose() everything, as in some cases the Finalize() method is a better choice.
Assuming that I am still in good shape so far, and my understanding of the Garbage Collector's behavior is valid.
I would consider that SqlCommand (full code reference here), would then also dispose of SqlReader, which would mean that you could just get away with:
using (SqlCommand command = new SqlCommand(queryString, connection))
{
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
// ...
}
}
which in your case would translate to:
using (var cmd = data.CreateCommand(sql))
{
var reader = cmd.ExecuteDataReader();
// ...
}

Optimized way to create OracleConnection and Command objects in c#

I have the following code in DAL layer:
using(OracleConnection conn= new OracleConnection(connString))
using(OracleCommand cmd = new OracleCommand(sql.ToString(), conn))
{
conn.Open();
}
The above object creation is done at multiple places of DAL methods. I am looking if there is any way to optimize this object creation, instead of repeating it several times in my code.
Any suggestions/advise would be helpful.
Thanks,
WH
There's really not a good way to do this without requiring almost the same amount of code each time to make sure you set it up properly because it needs to be disposable. Anything outside of this: using(OracleCommand cmd = new OracleCommand(sql.ToString(), conn)) will despose the connection. Is there a reason why you can't move to using an ORM like Entity Framework? That aside you can create a class that will return a OracleConnection that you would then call .Open() on but you would need to inherit IDisposable and call .Dispose() on it when you are done or you will fill up your app pool. You could do something like this in a data manager class:
public void RunQuery(string query)
{
using(OracleConnection conn= new OracleConnection(connString))
using(OracleCommand cmd = new OracleCommand(query, conn))
{
conn.Open();
//do your data transaction here
}
}
That would let you pass queries to a single place to be handled. Still not a great solution but will let you keep it in one place. To use it:
new YourDataClass().RunQuery("INSERT...");
You would need a few different classes to handle things like selects, etc to return data if needed.
Edit: This is just conceptual. You would have a single data class and just send queries to it. Then you aren't reproducing the same connection code everywhere. You'll need to add more to this to have it cover all aspects of interfacing with your database but this is the general concept. This is written in one class and used over and over in your application. Again, an ORM would be far better but this will accomplish what you're trying to do.
public class YourDataClass
{
public void RunQuery(string query) //for add, update where you don't want to return anything, could add a second parameter to send in a List<SqlParameter> to add data.
{
using(OracleConnection conn= new OracleConnection(connString))
using(OracleCommand cmd = new OracleCommand(query, conn))
{
conn.Open();
//do your data transaction here
cmd.ExecuteNonQuery();
}
}
public DataTable GetData(string query) //for selecting data
{
using(OracleConnection conn= new OracleConnection(connString))
using(OracleCommand cmd = new OracleCommand(query, conn))
{
conn.Open();
//do your data transaction here
dt.Add(cmd); //add data to data table or dataset
return dt;
}
}
}

Which pattern is better for SqlConnection object?

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 ...

Using block around a static/singleton resource reference

This is interesting (to me anyway), and I'd like to see if anyone has a good answer and explanation for this behavior.
Say you have a singleton database object (or static database object), and you have it stored in a class Foo.
public class Foo
{
public static SqlConnection DBConn = new SqlConnection(ConfigurationManager.ConnectionStrings["BAR"].ConnectionString);
}
Then, lets say that you are cognizant of the usefulness of calling and disposing your connection (pretend for this example that its a one-time use for purposes of illustration). So you decide to use a 'using' block to take care of the Dispose() call.
using (SqlConnection conn = Foo.DBConn)
{
conn.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "SP_YOUR_PROC";
cmd.ExecuteNonQuery();
}
conn.Close();
}
This fails, throwing an exception on the call to open the connection, stating that the "ConnectionString property is not initialized". It's not an issue with pulling the connection string from the app.config/web.config. When you investigate in a debug session you see that Foo.DBConn is not null, but contains empty properties.
Why is this?
A little out of topic and not really answering your question but why using a singleton for SqlConnection when ADO.NET already uses a connection pool? Your code could have very well looked like this:
using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["BAR"].ConnectionString))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.Connection = conn;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "SP_YOUR_PROC";
cmd.ExecuteNonQuery();
}
And one less thing to worry about in your program: connection lifecycle
Perhaps you do not have the corresponding connectionStrings node in you web/app.config?
<connectionStrings>
<add name="BAR"
connectionString="Data Source=localhost\sqlexpress;Initial Catalog=mydatabase;User Id=myuser;Password=mypassword;" />
The static field is evaluated sometime before it is used (not deterministically). See beforefieldinit for more detail. So the system may not be ready for creating an SQL-connection when it is called or maybe even properly create the static field after you use it.
Additionally, how would you handle a second SQL-command after you closed the first one? I don't know exactly how SqlConnection works, but after closing (note that this cals Dispose) and disposing the connection, your static Foo.DBConn should be gone, i.e. it won't be reevaluated.
If you want to keep your basic infrastructure, I would replace the static field with a static property which returns a new SqlConnection on get:
public static SqlConnection DBConn
{
get
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["BAR"].ConnectionString);
}
}

Categories