FOLLOW UP TO MARC GRAVELLS SUGGESTION IN THIS QUESTION
I now have something like this repeated several times in my code:
using (var conn = CreateConnection())
using (var dataCommand = conn.CreateCommand())
{
conn.Open();
[...]
}
Is the following correct for the factory method CreateConnection()? Or will it be error prone? (note: I'm only ever going to call it from a using directive)
SqlConnection CreateConnection()
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["IMS"].ConnectionString);
return conn;
}
Or would there be a case for amending this method and having the Open in it as well?
Your code is the typical example of static factory method.
Factory Pattern is a part of Software Design Patterns, which are general reusable solutions to a commonly occurring problem within a given context in software design. I can suggest you to read Head First Design Patterns which is a very good starter book to understand design patterns.
Couple of suggestions about your code:
Make the factory method static, it doesn't use any instance variables etc.
Not related but, you don't need to use a local variable in your factory method, you can directly return the connection.
Now your method looks like this:
static SqlConnection CreateConnection(){
return new SqlConnection(ConfigurationManager.ConnectionStrings["IMS"].ConnectionString);
}
You might wanna check if the ConnectionStrings["IMS"] is null before calling the constructor of SqlConnection. No further error handling is required in this class because it doesn't initiate the connection.
Let's say you want to return an open connection and handle connection errors in the same method:
static SqlConnection CreateConnection()
{
if (ConfigurationManager.ConnectionStrings["IMS"] == null)
{
throw new Exception("Connection string not found in the configuration file.");
}
var sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["IMS"].ConnectionString);
try
{
sqlConnection.Open();
}
catch (Exception exception)
{
throw new Exception("An error occured while connecting to the database. See innerException for details.", exception);
}
return sqlConnection;
}
If you want, you can create your own exception classes to handle these exceptions later. See ASP MVC N-Tier Exception handling. You can also return null if an exception occurs, but check "Is returning null bad design?" first.
Factory and Singleton:
My rantings. Corrections welcome!!
Functionally, I have seen a disconnect in the way developers understand factory pattern. In simple
sense, a factory will and should give a product. (eg: if you have a "Car Factory" it should give a "Car").
Having said that, you implement factory pattern only when you don't want instantiation logic to be exposed
and there is a need to create different concrete products. In your case , if your need is
always a SQL object(one kind of product) then why Factory?
You can argue about extensibility and scalability but that is subjective. Most companies just live with either
SQL server or Oracle for ages and you will not use the scalability that you built in your product.
I believe, you can live well with a Singleton pattern (or) a even simpler class with static members.
Another important method to have is CloseConnection() method.
In your original code, you have used using which kills and disposes the object but in your new
static implementation , you may want to build it.
public static void CloseConnection(SQLConnection conn)
{
if (conn.State == ConnectionState.Open)
{
conn.Close();
conn.Dispose();
}
}
Related
i am writing a windows form based application that uses database and
i want to declare the following as global so that i can just use vcon.open()
and vcon.close() to open and close my database from which ever form i want. please tell how to do it.
OleDbConnection vcon = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=F:\workspace\RDASMS\RDASMS\rdadb.mdb");
Connections are quite lightweight, so you can just create and close them as needed. Maybe like this:
using (var conn = new OleDbConnection(connStr))
{
// Use your connection
}
This will automatically close the connection for you when the block exits.
You might like to put the string in a globally accessible place, such as a Config class.
As the others have stated, "global" static types are not usually the best design approach, but to answer your specific question:
namespace YourApplicationNamespace
{
public static class MyOleDbConnection
{
public static OleDbConnection OleDbConnection;
public static void Open()
{
// Do Something with OleDbConnection.
}
public static void Close()
{
// Do Something with OleDbConnection.
}
}
}
Can be used as:
MyOleDbConnection.Open();
MyOleDbConnection.Close();
First of all you can't declare something global in a namespace. And even if it was possible it is not a nice idea. Appreciating your effort in avoiding code duplication, I suggest you to:
Place the connection string in the configuration.
Declare the connection and use it when needed, maybe with an using pattern.
a point about 2: I noticed you use a jet engine ( Access ) this can result in a performance drawback by opening and closing the connection on demand, or at least was as this in the past. In any case note than opening the connection when needed and close it as soon you have done is the pattern to follow in any other case.
You can create a static class with static members.
public static MyConnection
{
public static OleDbConnection Connection = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=F:\workspace\RDASMS\RDASMS\rdadb.mdb");
}
Then you can access it like:
var vcon = MyConnection.Connection;
vcon.Open();
Doing it this way adds a unnecessary layer of complexity to your program. You should either create a class that strictly handles database access such as the MyConnection example above. You would need to add the appropriate methods to actually handle the access. Using the Jet provider can introduce significant performance implications when opening and closing a file constantly. You should only close it if there will be long periods of inactivity on the connection. In that case you should do something more along the lines of:
using(var vcon = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=F:\workspace\RDASMS\RDASMS\rdadb.mdb"))
{
// Your code here...
}
This will close the connection once your operations are complete. But don't forget about the performance issues that can arise from this.
If methods/functions I'm going to call involve the need of an open SqlConnection, I will open this up in the method which is calling the function. For example:
protected static void btnSubmit(){
conn.Open();
myMethod(someParam, conn);
conn.Close();
}
protected static void myMethod(object someParam, SqlConnection conn){
//Some SQL commands etc here..
}
I do this so that I:
Only ever open and close 1 SqlConnection per process
However, would it be better to structure my code like so:
protected static void btnSubmit(){
myMethod(someParam);
}
protected static void myMethod(object someParam){
SqlConnection conn = New SqlConnection(".....");
conn.Open();
//Some SQL commands etc here..
conn.Close();
}
The advantage I see of structuring it this way is:
I don't have to pass an extra parameter for each method
If later down the line the method no longer has a SQL command, there is not an unused parameter being called each time
The disadvantage I see to this, is:
If myMethod is a recursive method, then when it calls itself its going to be opening another SqlConnection, and so on, and so on..
If btnSubmit is calling multiple methods which all require a SqlConnection, each one is going to open and close a new connection.
What is the best way of doing this, and which is most commonly practised?
ADO.NET uses connection pooling, so it automatically reuses existing opened connections, even when you think that you are opening a new connection. Having that in mind, there is really no reason to pass a connection through your code (as a parameter). This will make your code much cleaner, with the same performance as when you were passing the connection as a parameter.
More details here
Also (and this is really important), please, use the "using" keyword. That way, you will not have to deal with closing the connection and cleanup, because your code as it is written now doesn't deal with closing the connections, so in a case of some exception you might end up with hitting connection limit on your server. Go with something like this:
using(var connection = new SqlConnection(<connection_string>))
{
connection.Open();
using(var command = connection.CreateCommand())
{
}
}
As you can see, there is no need to call connection.Close() or deal with exceptions and closing the connection in your finally block, because that is a "job" for the "using" block.
Also, one important note...transactions are not passed via connection polling, so if you want to keep your transaction across method calls, you will have to pass your connection (and that is the only reason I can think of why you should do that).
The best pattern to use is Repository+UnitOfWork patterns.
So repository is created and passed the UnitOfWork which contains the connection. After work is done UnitOfWork is disposed.
// Pseudocode
using(UnitOfWork uow = new UnitOfWork())
{
Repository.Init(uow);
Repository.SaveInDb(stuff);
}
And Unit of work:
// PseudoCode
class UnitOfWork : IDisposable
{
public UnitOfWork()
{
conn = new SqlConnection();
conn.Open();
}
public void Dispose()
{
conn.Close();
}
....
}
This is what I always use.
Some people prefer simpler approach where Repository owns connection. This is simpler but in case you need to have a transaction across multiple repositories, it will not work.
Is this good enough ? do I need to add anything or remove anything ? like a rollback to my Sql Queries ? add catch() ? should my function accept only the property that I need or the object it self ? and how can I let the presentation layer know that the function's code was executed with no errors .. should I make it book instead of void or what ?
public static void DeleteAllCabinFeaturesFromACruise(int CruiseID)
{
string commandText = "DELETE FROM Cruise_Features WHERE CruiseID = #cruiseId";
SqlConnection connection = new SqlConnection(ConnectionString);
SqlCommand command = new SqlCommand(commandText, connection);
try
{
using (connection)
{
using (command)
{
command.Parameters.AddWithValue("#cruiseId", CruiseID);
connection.Open();
command.ExecuteScalar();
}
}
}
finally { connection.Close(); }
}
You are not using using correctly. The idea of using is to wrap some resource, that needs to be released in a safety-west, that protects it from exceptions. So, the correct way of using using (ha-ha) is the following:
using(SqlConnection connection = new SqlConnection(ConnectionString)){
{
using(SqlCommand command = new SqlCommand(commandText, connection)){
//your code here
}
}
The second issue is that you are executing your query as if it should return Scalar value. It's OK, but I think it's better use just Execute: command.Execute(); And, if you want some error handling, you'd better wrap
connection.Open();
command.ExecuteScalar();
in a try ... catch block like you have. Like this:
//I would place it inside inner-most using block, but nothing wrong placing it outside
try{
connection.open();
command.Parameters.AddWithValue("#cruiseId", CruiseID);
command.Execute();
}
//this catches ALL exceptions, regardless of source. Better narrow this down with
//some specific exception, like SQLException or something like that
catch (Exception e){
return false; //or whatever you need to do
}
You can remove the try...finally block. The "using" will take care of disposing the connection for you.
EDIT: As chibacity says, you should initialise the connection in the using to ensure correct disposal. Your error-handling (to prevent the users seeing the exception details) should be done in your UI layer, not your data-layer. It is entirely appropriate for a data-layer to throw exceptions.
string commandText = "DELETE FROM Cruise_Features WHERE CruiseID = #cruiseId";
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
SqlCommand command = new SqlCommand(commandText, connection);
// Your code.
}
For a simple query like that a rollback is probably not necessary - the query will either succeed or fail. For a more complicated query, a rollback would be necessary if you wanted to ensure that operations were atomic.
and how can I let the presentation layer know that the function's code was executed with no errors?
This really boils down to how you want to handle these cases in general. One rule of thumb is to ask yourself a question; are you expecting an error to occur significantly often, or not? So, for example, if the method should only fail if there was a communication error, then it's perfectly fine to throw an exception to the front-end. If, on the other hand, the delete operation can fall over because of various business rules that need to be validated (or, say, foreign key violations), then you should probably not throw those as exceptions. In the latter case, your method should return some information about success (simplistic version: a boolean, complex version: your own "OperationResult" class).
I'm simplifying things a lot here, but I believe these rules of thumb are valid.
EDIT: When I say "then it's perfectly fine to throw an exception to the front-end", I mean - throw it to the front end, but have the front-end handle it gracefully!
connection.Close() is redundant - using(connection) will dispose and close it.
Also, connection.Open() is usually placed in the beginning - to verify connection with the server .
This is a little wierd, but I want to check if connection to my database is already open or not? How do I check that? and if open I want to be able to work with it straightaway without going through all the statements:
sqlconnection conn = new sqlconnection("string ...");
Can this be done? I know the connection string and the connection name too. I want to check if this connection is available first and then proceed.
If you know the connection string then the easiest way of obtaining a new usable sql connection is to create a new instance of the SqlConnection class:
using (SqlConnection conn = new SqlConnection("MyConnectionString"))
{
conn.Open();
// Use the connection
}
The .Net framework uses connection pooling and so there is no need to worry about opening efficiency & multiple connections - the above code will either re-use an available existing connection, or create a new one as required.
If you want to save yourself some typing then you might find it useful to create yourself a small helper method or property:
class SqlHelper
{
public static SqlConnection GetConn()
{
SqlConnection returnValue = new SqlConnection("MyConnectionString");
returnValue.Open();
return returnValue;
}
}
Usage:
using (SqlConnection conn = SqlHelper.GetConn())
{
// Use the connection
}
Have you looked at the documentation for SqlConnection?
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.aspx
I believe the "State" property will tell you what you want.
If you are rather asking more generally how you can use an existing connection from a connection pool, this will be done automatically when you create a new SqlConnection with an identical connection string as an active connection.
If you're just trying to avoid writing redundant code, then put it in a class and reuse it.
Although you are probably just using SQL Server it might be good practice to get familiar with all the core interfaces in System.Data since all data providers implement them. I believe the State property on IDbConnection returns the information you are asking for (IDbConnection)
Also you may want to hide that logic in some kind of centralized method:
public static IDbConnection RetrieveConnection(){
if(DataAccess.Connection.State == ConnectionState.Open) return DataAccess.Connection;
conn.Dispose(); //to be clean, I believe this is safe if it's already disposed
//retrieve configured connection string
//create and open connection
return DataAccess.Connection;
}
So maybe DataAccess is some place you can put and retrieve your connection object, but I would avoid having everyone use it directly. Instead have them go through this method that can ensure the connection is usable. I'm just trying to give you ideas.
Also you may want to take it a step further and use something like NHibernate that will manage connections and all that stuff for you. Although that's not always worth the effort if the project is small.
EDIT: made the code a little more explicit
The Façade Design Pattern should help you here. Here's an example.
Façade Pattern (wikipedia);
Façade Design Pattern (Gang of Four).
An "intelligent" façade knows what method needs to connect where, etc. The façade opens the connection and pass it to an underlying piece of code, generally contained in a factory class or something alike.
public class DoSomethingFacade {
private static readonly DoSomethingFactory _doSomethingFactory = new DoSomethingFactory();
public static IList<T> GetList<T>() {
using(IDbConnection connection = OpenConnection("string..."))
return _doSomethingFactory.GetList<T>(connection);
}
public static IDbConnection OpenConnection(string connectionString) {
IDbConnection openedConnection = new SqlConnection(connectionString);
openedConnection.Open();
return openedConnection;
}
}
internal class DoSomethingFactory {
internal DoSomethingFactory() { }
internal IList<T> GetList<T>(IDbConnection connection) {
IList<T> results = new List<T>();
// use connection here without caring about it,
// as it should be provided as an opened available connection.
return results;
}
}
Was wondering if it is recomended to pass a database connection object around(to other modules) or let the method (in the other module) take care of setting it up. I am leaning toward letting the method set it up as to not have to check the state of the connection before using it, and just having the caller pass any needed data to the calling method that would be needed to setup the connection.
Personally I like to use tightly scoped connections; open them late, use them, and close them (in a "using" block, all within the local method). Connection pooling will deal with re-using the connection in most cases, so there is no real overhead in this approach.
The main advantage in passing connections used to be so that you could pass the transaction around; however, TransactionScope is a simpler way of sharing a transaction between methods.
Since the classes are implementation specific, I'd write each to open it's own native transaction. Otherwise, you can use the ado.net factory methods to create the appropriate type from the config file (the provider name).
Personally, I like storing a stack of my current open connection and transactions on top of the Thread Local Storage using SetData and GetData. I define a class that manages my connections to the database and allow it to use the dispose pattern. This saves me the need to pass connections and transactions around, which is something that I think clutters and complicates the code.
I would strongly recommend against leaving it up to the methods to open connections every time they need data. It will leads to a really bad situation where it is both hard to manage transactions throughout the application and too many connections are opened and closed (I know about connection pooling, it is still more expensive to look up a connection from the pool than it is to reuse an object)
So I end up having something along these lines (totally untested):
class DatabaseContext : IDisposable {
List<DatabaseContext> currentContexts;
SqlConnection connection;
bool first = false;
DatabaseContext (List<DatabaseContext> contexts)
{
currentContexts = contexts;
if (contexts.Count == 0)
{
connection = new SqlConnection(); // fill in info
connection.Open();
first = true;
}
else
{
connection = contexts.First().connection;
}
contexts.Add(this);
}
static List<DatabaseContext> DatabaseContexts {
get
{
var contexts = CallContext.GetData("contexts") as List<DatabaseContext>;
if (contexts == null)
{
contexts = new List<DatabaseContext>();
CallContext.SetData("contexts", contexts);
}
return contexts;
}
}
public static DatabaseContext GetOpenConnection()
{
return new DatabaseContext(DatabaseContexts);
}
public SqlCommand CreateCommand(string sql)
{
var cmd = new SqlCommand(sql);
cmd.Connection = connection;
return cmd;
}
public void Dispose()
{
if (first)
{
connection.Close();
}
currentContexts.Remove(this);
}
}
void Test()
{
// connection is opened here
using (var ctx = DatabaseContext.GetOpenConnection())
{
using (var cmd = ctx.CreateCommand("select 1"))
{
cmd.ExecuteNonQuery();
}
Test2();
}
// closed after dispose
}
void Test2()
{
// reuse existing connection
using (var ctx = DatabaseContext.GetOpenConnection())
{
using (var cmd = ctx.CreateCommand("select 2"))
{
cmd.ExecuteNonQuery();
}
}
// leaves connection open
}
For automated testing purposes, it's usually easier to pass it in. This is called dependency injection.
When you need to write tests, you can create a mock database connection object and pass that instead of the real one. That way, your automated tests won't rely on an actual database that needs to be repopulated with data every time.
I personally work to centralize my data access as much as possible, however, if not possible I ALWAYS open a new connection in the other classes, as I find that there are too many other things that can get in the way when passing the actual connection object.
Here is a little more insight into this problem. I have a class that manages db connections, and have 2 classes that implement an interface. One of the classes is for SQL and the other is of OLAP. The manager is the one that knows which connection to use, so it could pass the exact connection to the type, or the type can create his own connection.
You can pass connection objects without any problem (for instance Microsoft Enterprise Library allows static method calls passing in a connection) or you could manage it externally its up to your design, there are not direct technical tradeoffs.
Be careful for portability not to pass an specific connection if your solution will be ported to other databases (meaning don´t pass a SqlConnection it you plan to work with other databases)
Setting up the connection is potentially expensive and potentially adds a round trip. So, again, potentially, the better design is to pass the connection object.
I say potentially, because if you are a Microsoft ADO app, you are probably using a connection pool....
I would suggest that you distinguish between the connection object and its state (open, closed).
You can have a single method (or property) that reads the connection string from web.config. Using the same version of the connection string every time ensures that you will benefit from connection pooling.
Call that method when you need to open a connection. At the very last moment, after setting up all of the SqlCommand properties, open the connection, use it, and then close it. In C#, you can use the using statement to make sure the connection is closed. If not, be sure to close the connection in a finally block.
I would use the web.config
<configuration>
<connectionStrings>
<add name="conn1" providerName="System.Data.SqlClient" connectionString="string here" />
<add name="conn2" providerName="System.Data.SqlClient" connectionString="string here" />
</connectionStrings>
</configuration>
Then you can reference it from anywhere in the application