So I noticed in my code I had a lot of repetitive connection strings and decided to clean it up a little bit.
My issue is, now that I've put the connection string into a seperate class I can no longer open the connection when using using (InfoTableConnection = new SqlConnection(infoTableConnString))
However if I don't use using it works fine.
I'm not quite understanding how it works I guess. Here is my code if someone could explain what exactly is happening once it's introduced to a class and/or how to fix it.
Connection Class: Connection.cs
class Connection
{
public static SqlConnection InfoTableConnection = null;
public void InfoConnection()
{
string infoTableConnString = "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=MTRInfoTables;Integrated Security=True";
using (InfoTableConnection = new SqlConnection(infoTableConnString))
InfoTableConnection.Open();
}
}
Sample Code from:
MainForm.cs
private void zGradeCombo()
{
try
{
//Connection string from class.
Connection connInfoTable = new Connection();
connInfoTable.InfoConnection();
SqlCommand cmd = new SqlCommand();
cmd.Connection = Connection.InfoTableConnection;
cmd.CommandText = "SELECT * FROM [dbo].[Item] ORDER by [Type] ASC";
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
cmbType.Items.Add(reader["Type"].ToString());
}
//Close connection from "Connection" class
Connection.InfoTableConnection.Close();
}
//Catch Exception
catch (Exception ex)
{
MessageBox.Show(this, ex.Message, "SQL ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
The using keyword makes sure that your object will be disposed when you reached the end of the scope so that all the resources will be cleaned up afterwards
using (InfoTableConnection = new SqlConnection(infoTableConnString))
{
InfoTableConnection.Open();
} // <- At this point InfoTableConnection will be disposed (and closed)
Since you care about disposing in the code around you do not need the using block in the constructor of the class. But it would be a good idea to implement IDisposable on your Connection class and use it like this:
using(var con = new Connection())
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con.InfoTableConnection;
cmd.CommandText = "SELECT * FROM [dbo].[Item] ORDER by [Type] ASC";
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
cmbType.Items.Add(reader["Type"].ToString());
}
}
In the Dispose() method of your connection you should dispose the SQL Connection.
If your goal is to have your connection string is one location, why not just place your connection string in your app.config (settings) file and reference it in the code from there?
app.config
<connectionStrings>
<add name="MyConnectionString" connectionString="Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=MTRInfoTables;Integrated Security=True" />
</connectionStrings>
code.cs
string myConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
You must include a reference to the System.Configuration.dll in your references to use ConfigurationManager.
This way, you can continue using your using statements they way that they were designed to be used.
Related
EDIT: I've just tested it in ASP.NET and it works perfectly fine. So no issue with the connection string or anything. Guess Unity doesn't like this method? Maybe there's some more DLL's I need to copy? Any ideas?
So I'm making a game in Unity and I'm trying to use the System.Data.SqlClient library to connect to some stored procedures I have made for things such as registering a user.
I have copied the System.Data.dll from "C:\Program Files\Unity\Editor\Data\Mono\lib\mono\unity" and that has all worked fine.
I'm currently using this connection string, which works fine on an ASP.NET application but just using a different mdf:
private string connectionString = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename='C:\Users\uppy8\Desktop\Computer Science Project\Mining Game\Assets\MineRace.mdf';Integrated Security = True";
The problem occurs when running this code:
using System.Data.SqlClient;
using System.IO;
public void Login()
{
Crypto crypto = new Crypto();
using (SqlConnection conn = new SqlConnection(connectionString))
{
try
{
conn.Open();
} catch (Exception e)
{
Debug.Log(e);
}
SqlCommand command = new SqlCommand("USERS_LOGIN_USER", conn);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#Username", usernameInputField.text));
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
if (crypto.EncryptString(passwordInputField.text) == reader["password"].ToString())
{
UserAccountManager.instance.userInfo = FetchUserInfo((int)reader["id"]);
}
}
}
}
The problem happens on the line "conn.Open()", where Unity gives me the error:
System.Net.Sockets.SocketException: No such host is known.
Furthermore, without the try catch, the error occurs where I create a new SqlDataReader, where I get this issue:
InvalidOperationException: ExecuteReader requires an open connection to continue. This connection is closed.
I understand that this is an issue with the connection, in that it's not running or the connection isn't working properly, however I can't seem to find a solution and I have a sneaky suspicion that it's something to do with Unity not supporting this library.
Some more clarification just before I end off:
The user enters their credentials into the "usernameInputField" and "passwordInputField"
The user presses Login, which runs the "Login" method shown above
The error occurs.
If any more information is required please leave a comment.
Thanks!
What is the scope of connectionString? Do you need to pass the connectionString to the Login() function?
public void Login(string connectionString)
I am a DBA, not a .Net developer, so forgive me if my questions are too basic or if my .Net syntax is wrong.
You can try this
string connectionString = #"Data Source = (localdb)\MSSQLLocalDB; Initial Catalog ='C:\USERS\uppy8\Desktop\Computer Science Project\Mining Game\Assets\MineRace.mdf'; Integrated Security = True; Connect Timeout = 30; Encrypt = False; TrustServerCertificate = True; ApplicationIntent = ReadWrite; MultiSubnetFailover = False"
SqlConnection con = new SqlConnection();
if (con.State==ConnectionState.Open)
{
con.Close();
con.ConnectionString = connectionString;
con.Open();
cmd.Connection = con;
}
else
{
con.ConnectionString = connectionString;
con.Open();
cmd.Connection = con;
}
I have a problem. I cannot fix the problem with The ConnectionString property has not been initialized. The problem is in this method:
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand cmd = new SqlCommand())
{
using (TransactionScope ts = new TransactionScope())
{
products.Update(dataSet, "Produktai");
offers.Update(dataSet, "Pasiulimai");
ts.Complete();
}
}
connection.Close();
}
}
catch
{ }
In the class constructor i already have a SqlDataAdapter and SqlCommandBuilder declared. My connection string is in App.config and it looks like this:
<connectionStrings>
<add name="connectionString" connectionString="server=ANDREW-PC\LTSMSQL;database=MarketDB; Integrated Security=true;" providerName="System.Data.SqlClient" />
In my program I already assigned this connection string parameter to string variable. Here is a code sample:
private string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString;
Any ideas how I can fix this error?
The command isn't assigned to the connection. You need to use the sqlcommand constructor like so: new SQLCommand(connection, "querystring"). I also suggest you use a newer technology such as ORM. I used basic ADO.NET data access before I found Fluent NHibernate, and Fluent is so much easier to use :-)
why are you using System.Transaction.TransactionScope? are you dealing with multiples transaction aware data sources such as sql server and oracle, where you need a transaction manager to coordinate the transaction? if not, then why don't you create a transaction from the connection?
using (var connection = new System.Data.SqlClient.SqlConnection(" "))
{
connection.Open();
var tran = connection.BeginTransaction();
var cmd = new System.Data.SqlClient.SqlCommand();
cmd.Connection = connection;
cmd.Transaction = tran;
//I dont know how the sql command relates to this
products.Update(dataSet, "Produktai");
offers.Update(dataSet, "Pasiulimai");
//commit
tran.Commit();
}
Ok, I just found the problem. For some reasons my database was "read only" for me when I connect with visual studio. I have changed some settings in the database and now it works fine. Thanks for your answers. :)
I used to call several functions with this connection string:
class Solders_DB
{
SqlConnection connection;
SqlCommand query;
String command;
public Solders_DB()
{
connection = new SqlConnection();
connection.ConnectionString = "Server=localhost;Database=Scheduling_Employee ;Trusted_Connection=True;MultipleActiveResultSets=True;";
query = new SqlCommand();
}
As you see I used this MultipleActiveResultSets=True; in my connection but in this function :
command = #"SELECT [GID] FROM [Scheduling_Employee].[dbo].[Solder] where [ID]=#ID";
query.CommandText = command;
query.Parameters.Clear();
query.Parameters.AddWithValue("#ID", id);
Object o= query.ExecuteScalar();
I faced with this error:
There is already an open datareader associated with this command which must be closed first
The code in your question is not complete. Please explain yourself better for further assistance.
When using a SqlConnection is recommended to use the 'using' statement like this:
using (SqlConnection SqlConn = new SqlConnection(ConnString))
{
try
{
SqlConn.Open();
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
return null;
}
}
You're trying to read data from the first execution of your query, please update your question and put the complete code and the error stack.
Its usually when there was another query before that one and has not yet stopped executing inside the database engine (maybe it was a heavy script). You could try query = new SqlCommand();, query.Cancel() or
while(query.Connection.State != System.Data.ConnectionState.Open){ Threading.Sleep(100);}
I am trying to make a simple MS Access Database connection by using the SqlConnection and SqlCommand objects.
As you can see here is how I make the connection:
private SqlConnection GetConnection()
{
String connStr = ConfigurationManager.ConnectionStrings[0].ConnectionString;
SqlConnection conn = new SqlConnection(connStr);
return conn;
}
And before you ask, yes I have tried to move this piece of code to the method that calls it. Didn't change anything. It still reads the connection string wrong.
The connection string looks like this and is located in the App.config file:
<add name="ConnString" connectionString="Server=*.*.*.*;Database=familie;User Id=mfs;Password=********;"/>
But when I get this error:
And look at the connection string object at the time, the string looks like this:
"data source=.\\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
I have spent about 2 hours now trying to make this work, going to many different sites to figure out what I did wrong, but I either get information is that is too old, conflicting or deals with connecting to a local database, when this is in fact an external one access through a proxy that was given to me by my client (TrustGate if anyone should ask)
The method that calls GetConnection() looks like this:
public Dictionary<int,String> GetPostNrList()
{
SqlConnection conn = GetConnection();
SqlCommand cmd = new SqlCommand("Execute dbo.HENT_POST_NR_LISTE", conn);
var reader = cmd.ExecuteReader();
Dictionary<int, String> liste = new Dictionary<int, string>();
while (reader.NextResult())
{
int post_nr = (int) reader.GetSqlInt32(0);
String by = reader.GetString(1);
liste.Add(post_nr, by);
}
CloseConnection(conn);
return liste;
}
What exactly am I doing wrong?
The exception message tells you exactly what the problem is - your connection is not open. You just need to open the connection prior to executing a command:
conn.Open();
BTW, a good pattern is to using a using block when dealing with SQL connections, to ensure it gets disposed properly:
using (var conn = GetConnection())
{
using (var comm = xxxxxxx)
{
conn.Open();
using (var rdr = comm.ExecuteReader())
{
// xxxxx
}
}
}
You don't have to specifically close anything - the using pattern does all that for you.
When I import Dataset to application in connnection string I choose "No exclude information from connection string. I will set this information in my aplication".
Now when I compile the form there is nothing to see in the DataGrid, where I must place connection in my application to connet ?
Now I have:
public Form1()
{
InitializeComponent();
using (OracleConnection con = new OracleConnection("Data Source=localhost;Persist Security Info=True;User ID=martynas;Password=xxxxxxx;Unicode=True"))
{
try
{
con.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = con;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
This conection is open, but DataGridView still does not show any records. I think that maybe I place connection in wrong method ?
You are not connecting your OracleCommand to anything. You create it but when it goes out of scope, it ceases to exists.