SqlConnection State is always Closed at Execution - c#

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.

Related

How can I fix "Keyword not suported: metadata" when opening a SQL Connection?

I'm trying to connect to a database, but it seems like my connection is not going through. I am using C# MVC for the webpage I'm creating. How can I fix the following error:
System.ArgumentException: 'Keyword not supported: 'metadata'.'.
The error is occuring on the line using (Sqlconnection con = new Sqlconnection(conStr)). What am I doing wrong on this line and is this how you call your SQL query in C# MVC?
string conStr = ConfigurationManager.ConnectionStrings["Training_DatabaseEntities"].ConnectionString;
List<FisYear> YerFis = new List<FisYear>();
using (SqlConnection con = new SqlConnection(conStr))
{
SqlCommand cmd = new SqlCommand("select * from [dbo].[FiscalYear]", con);
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
while(rdr.Read())
{
FisYear fy = new FisYear();
fy.FisDate = rdr["ST_FI"].ToString();
YerFis.Add(fy);
}
SelectList list = new SelectList(YerFis, "ST_FI", "FisDate");
ViewBag.DropdownList = list;
}
You're almost certainly trying to use an entity framework connection string to open a connection via new SqlConnection, which won't work.
If you look in your web.config file you'll probably see something similar to:
<connectionStrings>
<add name="Training_DatabaseEntities" connectionString="metadata=res://*/Entity.csdl|res://*.............provider=System.Data.SqlClient;provider connection string=............." />
</connectionStrings>
You could try parsing the connection string by hand to retrieve the bit you actually want, a brief web search suggests that the EntityConnectionStringBuilder may be of use to retrieve it programmatically, here's an example of doing that in a console app:
var connectionString = ConfigurationManager.ConnectionStrings["Training_DatabaseEntities"]
.ConnectionString;
var entityConnectionStringBuilder = new EntityConnectionStringBuilder(connectionString);
var sqlConnectionConnectionString = entityConnectionStringBuilder.ProviderConnectionString;
Console.WriteLine($"EF Connection String: {connectionString}");
Console.WriteLine($"SqlConnection Connection String: {sqlConnectionConnectionString}");
This gives the output (my emphasis):
EF Connection String: metadata=res:///Models.Model1.csdl|res:///Models.Model1.ssdl|res://*/Models.Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=cntrra02-sql-rs;initial catalog=Training_Database;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"
SqlConnection Connection String: data source=cntrra02-sql-rs;initial catalog=Training_Database;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework
Which shows a connection string that can be passed into a SqlConnection instance.

How do I connect to a Local MSSQL Database

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;
}

C# SQL connection String in class connection issue

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.

Need help (The ConnectionString property has not been initialized)

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

C# :error There is already an open DataReader associated with this Command which must be closed first

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);}

Categories

Resources