Firstly, am new to C# programming.
I have created a dedicated class to get the connection string from the app.config of a Web Services application in Visual Studio 2010 as per the code below.
On building the code I get the following error via the catch block:
"The name 'connection' does not exist in the current context".
Obviously connection is going out of scope.
How do I avoid this error?
Is the Dispose method being used correctly here?
public class FCSConnection : IDisposable
{
public string GetDefaultConnectionString()
{
string DefaultConnectionString = null;
try
{
DefaultConnectionString = ConfigurationManager.AppSettings["ConnectionString"];
SqlConnection connection = new SqlConnection(DefaultConnectionString);
connection.Open();
return DefaultConnectionString;
}
catch (Exception)
{
if (DefaultConnectionString != null)
{
connection.Dispose();
}
}
return DefaultConnectionString;
}
public void Dispose()
{
throw new NotImplementedException();
}
}
The exact compiler message refers to your catch statement:
connection.Dispose();
Here, connection is an unknown name, because it's declared inside the try block.
As for your entire code, I think it's also wrong. If you want your FCSConnection class to encapsulate the SQL connection, you should declare connection as a private member and then dispose it in your Dispose() method.
public class FCSConnection : IDisposable
{
private SqlConnection connection = null;
public string GetDefaultConnectionString()
{
string defaultConnectionString = null;
try
{
defaultConnectionString = ConfigurationManager.AppSettings["ConnectionString"];
connection = new SqlConnection(defaultConnectionString);
connection.Open(); // are you sure want to keep the connection being opened??
}
catch
{
Dispose();
}
return defaultConnectionString;
}
public void Dispose()
{
if (connection != null)
{
connection.Dispose();
connection = null; // to avoid repeat dispose
}
}
}
Related
I'm getting error: Connection must be valid and open when I start this program.
It works fine, but sometimes it happens
There is no problem with connection information and query syntax.
Please Help.
public class Connector : IDisposable
{
private MySqlConnection mySqlConnect;
public MySqlConnection MySqlConnect
{
get { return mySqlConnect; }
}
public Connector()
{
mySqlConnect = new MySqlConnection(DatabaseInformation.ConnStr);
Open();
}
private int Open() // Try Connect
{
try
{
if (mySqlConnect.State == ConnectionState.Closed)
mySqlConnect.Open();
return -1;
}
catch (MySqlException ex)
{
return ex.Number;
}
}
private int Close() // Try Disconnect
{
try
{
if (mySqlConnect.State == ConnectionState.Open)
mySqlConnect.Close();
return -1;
}
catch (MySqlException ex)
{
return ex.Number;
}
}
public void Dispose()
{
Close();
mySqlConnect.Dispose();
}
}
see this below code
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.local);
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.remote);
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.OrcsWeb);
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.Sage);
Unity RegisterType not accepting enum but when if i pass string then no problem occur but i have to use enum. my full code as follow. so some one see my code and tell me what and where to fix in code as a result enum should be accepted.
full code
public enum ConType { local, remote, OrcsWeb, Sage, };
public interface IBBAConnection
{
IDbConnection GetConnection();
string ConType { get; set; }
}
public class BBAConnection : IBBAConnection
{
public ConType ConType { get; set; }
public IDbConnection GetConnection()
{
string _connectionString = "";
IDbConnection connection = null;
try
{
// inside if else logic we fetch connection string from ini file or from any source and inistialize connection.
if (ConType == ConType.local)
{
_connectionString = "put here local db connection";
connection = new System.Data.SqlClient.SqlConnection(_connectionString);
}
else if (ConType == ConType.remote)
{
_connectionString = "put here remote db connection";
connection = new System.Data.SqlClient.SqlConnection(_connectionString);
}
else if (ConType == ConType.OrcsWeb)
{
_connectionString = "put here website db connection";
connection = new System.Data.SqlClient.SqlConnection(_connectionString);
}
else if (ConType == ConType.Sage)
{
_connectionString = "put here sage connection";
connection = new System.Data.SqlClient.SqlConnection(_connectionString);
}
connection.Open();
}
catch (Exception ex)
{
string strErr = ex.Message;
}
return connection;
}
}
public static class Factory
{
static IUnityContainer cont = null;
public static IBBAConnection initialize(ConType oConType)
{
IBBAConnection oDbConnection = null;
cont = new UnityContainer();
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.local);
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.remote);
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.OrcsWeb);
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.Sage);
oDbConnection = cont.Resolve<IBBAConnection>(oConType);
//oDbConnection.ConType = type;
return oDbConnection;
}
}
looking for guide line that what to change as a result Enum should be accepted.
Below is what I think you should do.
It will dramatically reduce the complexity of BBAConnection because you're letting your IConnectionConfig binding determine the connection string you need.
public interface IConnectionConfig
{
string GetConnectionString();
}
public class LocalConnectionConfig : IConnectionConfig
{
public string GetConnectionString()
{
return "db connection for local";
}
}
public class BBAConnection : IBBAConnection
{
private readonly IConnectionConfig config;
public BBAConnection(IConnectionConfig config)
{
this.config = config;
}
public IDbConnection GetConnection()
{
string _connectionString = "";
IDbConnection connection = null;
try
{
connection = new System.Data.SqlClient.SqlConnection(this.config.GetConnectionString());
connection.Open();
}
catch (Exception ex)
{
string strErr = ex.Message;
}
return connection;
}
}
The registrations:
container.RegisterType<IBBAConnection, BBAConnection>();
container.RegisterType<IConnectionConfig, LocalConnectionConfig>();
Conceptually Speaking
You would normally let your build configurations define what configs you are using. You can then use that in your code to define which config you need.
I have a unitofWork class and a repository that uses it
something along the lines of this:
unit of work
private SqlConnection _conn;
private TransactionScope _ts;
public UnitOfWork(SqlConnection conn, TransactionScope ts)
{
_ts = ts;
_conn = conn;
_conn.EnlistTransaction(Transaction.Current);
}
public SqlConnection Connection
{
get { return _conn; }
}
public void Save()
{
_ts.Complete();
}
#region IDisposable
public void Dispose()
{
if (_conn != null)
{
_conn.Dispose();
_conn = null;
}
if (_ts != null)
{
_ts.Dispose();
_conn = null;
}
}
repository
SqlConnection _conn;
public Repository(IUnitOfWork uow)
{
_conn = uow.Connection;
}
// some methods
public void Dispose()
{
if (_conn != null)
{
_conn.Dispose();
_conn = null;
}
}
I am using it like this
using (var uow = new UnitOfWork())
{
using (var repo = new Repository(uow))
{
if (repo.UpdateStuff())
{
uow.Save();
}
}
}
the dispose method is first called in the repo, which disposes and nulls the connection. but then when it we get to the uow dispose, the connection is no longer null and is disposed 'again'
I am sure I am being dull, but can anyone explain please
thanks
The right part of the statement
_conn = uow.Connection;
actually returns a copy of the object reference, not the reference itself.
So what you're setting to null in the Repository Dispose method is the local reference to the connection, which is different from the connection reference in the UnitOfWork instance.
If you really want to keep this behavior ( having the UnitOfWork Connection property set to null by the Repository Code), you must set the uow.Connection to null, not the local reference _conn.
I tried to close a connection in the destructor of my class, to be sure that if I forget to close it - it close automatically, and it fires an exception.
I searched a little and I founded here that It can't be done.
Now I tried to close it twice - and it works!!!
But I'm wondering if it's a good solution.
what do you think?
here is the code
public class MyCommand : IDisposable
{
public readonly DbCommand command;
public MyCommand(string ConnectionString, DbProviderFactory factory)
{
var tempConnexion = factory.CreateConnection();
tempConnexion.ConnectionString = ConnectionString;
tempConnexion.Open();
var t = tempConnexion.BeginTransaction(IsolationLevel.ReadCommitted);
command = tempConnexion.CreateCommand();
command.Connection = tempConnexion;
command.Transaction = t;
}
public MyCommand(string ConnectionString, DbProviderFactory factory, string requete)
: this(ConnectionString, factory)
{
command.CommandText = requete;
}
public MyCommand(string ConnectionString, string provider)
: this(ConnectionString, DbProviderFactories.GetFactory(provider)) { }
public MyCommand(string ConnectionString, string provider, string requete)
: this(ConnectionString, DbProviderFactories.GetFactory(provider), requete) { }
public static implicit operator DbCommand(myCommand c)
{
return c.command;
}
public void Dispose()
{
try
{
var t = command.Transaction;
if (t != null)
{
t.Commit();
t.Dispose();
}
}
catch { }
try
{
if (command.Connection != null)
command.Connection.Dispose();
command.Dispose();
}
catch { }
}
~MyCommand()
{
if (command != null && command.Connection != null && command.Connection.State == ConnectionState.Open)
for (int i = 0; i < 2; i++)//twice to get the handle - it's working!
Dispose();
}
}
The connection is closed by the Dispose method not by the Destructor.
Also see the MSDN caution
Caution
Do not call Close or Dispose on a Connection, a DataReader, or any
other managed object in the Finalize method of your class. In a
finalizer, you should only release unmanaged resources that your class
owns directly. If your class does not own any unmanaged resources, do
not include a Finalize method in your class definition.
A much better and recommended way to deal with connection is to use USING statement which is equivalent to saying like
try
{
// your code
}
finally
{
myobject.Dispose();
}
I have an SQL database.
Then in one class I have an ExcelFunction:
[ExcelFunction(Description = "fonction de recherche")]
public static double id(string _isin)
{
double res;
res =DBSQL.Instance.getID(_isin);
return res;
}
Then in anoher class I have my connection and the creation of the singleton pattern (in order to be safe in case of multi-threading). The idea might not be clear, just ask me and I will try to explain. The point is to open a connection (using the singleton pattern), then do the request and then delete the singleton to close the connection.
Here is my code :
public class DBSQL : iAccesDB1
{
private SqlConnection MaConn = new SqlConnection("sefhgoefhouzeyf");
private static volatile DBSQL instance;
private static object syncRoot = new Object();
private DBSQL() {}
public static DBSQL Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new DBSQL();
}
}
return instance;
}
}
public void Connection()
{
MaConn.Open();
}
public void CloseConnection()
{
MaConn.Close();
}
public double getID(String _isin)
{
SqlDataReader rd;
double res = -9999;
SqlCommand cd = new SqlCommand("select cpn from tD where isin='" + _isin + "'", MaConn);
try
{
rd = cd.ExecuteReader();
if (rd.HasRows)
{
while (rd.Read())
res =double.Parse(rd["cpn"].ToString());
}
}
catch (Exception ex)
{
throw new Exception("1000: " + ex.Message);
}
return res;
}
}
The problem is that it does not work - in my excel cell I have the following: VALUE?
When your Excel-DNA function returns #VALUE to Excel, it probably means there was an unhandled exception.
I suggest you change your top-level function to return an 'object' which returns an error string if there is an exception, like this:
[ExcelFunction(Description = "fonction de recherche")]
public static object id(string _isin)
{
try
{
double res;
res = DBSQL.Instance.getID(_isin);
return res;
}
catch (Exception ex)
{
return "!!! ERROR: " + ex.ToString();
}
}