This is really simple, all i'm trying to do is fill a datatable, i have everything surrounded by using() and the connection will not dispose/close. Please help
DataTable loginTbl = MySQLProcessing.MySQLProcessor.StoreProcedureDTTable("Login", ParamArgs, "Login");
public static DataTable StoreProcedureDTTable(string mysqlQuery, List<string> CommandArgs, string queryName)
{
DataTable DTTableTable = new DataTable();
using (MySqlCommand MySQLCommandFunc = new MySqlCommand(mysqlQuery))
{
MySQLCommandFunc.CommandType = CommandType.StoredProcedure;
foreach (string args in CommandArgs)
{
string[] splitArgs = args.Split('|');
MySQLCommandFunc.Parameters.AddWithValue(splitArgs[0], splitArgs[1]);
}
using (MySqlDataAdapter DataDTTables = new MySqlDataAdapter(MySQLCommandFunc))
{
DataDTTables.SelectCommand.CommandTimeout = 240000;
lock (_object)
{
using (MySqlConnection con = new MySqlConnection(ConfigurationManager.ConnectionStrings["mysqlCon"].ConnectionString))
{
MySQLCommandFunc.Connection = con;
DataDTTables.Fill(DTTableTable);
}
}
}
}
DataTable catchConnectionTable = DTTableTable;
DTTableTable.Dispose();
return catchConnectionTable;
}
Add Pooling=False to the connection string
Have you tried:
using (MySqlConnection con = new MySqlConnection(ConfigurationManager.ConnectionStrings["mysqlCon"].ConnectionString))
{
con.open();
MySqlDataAdapter DataDTTables = new MySqlDataAdapter(MySQLCommandFunc)
DataDTTables.SelectCommand.CommandTimeout = 240000;
MySQLCommandFunc.Connection = con;
DataDTTables.Fill(DTTableTable);
con.close();
}
?
Alternatives to Pooling=false are SqlConnection.ClearPool and SqlConnection.ClearAllPools methods. For more information read: SQL Server Connection Pooling (ADO.NET)
Related
This is probably a simple question but I am not experienced in C#.
I have 2 datatables, 1 is basically a copy of the other (like a table to review information). To set the values this is what I am doing now:
string attribute1 = "";
string attribute2 = "";
string attribute3 = "";
.....
DataTable result = new DataTable();
using (SqlConnection con = new SqlConnection("user id=user_id;password=pwd;server=serverstring;Trusted_Connection=yes;database=database;connection timeout=30"))
{
using (SqlCommand cmd = new SqlCommand("SELECT * FROM table1 WHERE parameter=#identifying_parameter", con))
{
cmd.Parameters.AddWithValue("#identifying_parameter", "example");
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
attribute1 = Convert.ToString(reader["attribute1"]);
attribute2 = Convert.ToString(reader["attribute2"]);
attribute3 = Convert.ToString(reader["attribute3"]);
.....
}
con.Close();
}
}
using (SqlConnection con = new SqlConnection("user id=user_2;password=pwd;server=serverstring;Trusted_Connection=yes;database=database;connection timeout=30"))
{
using (SqlCommand cmd = new SqlCommand("INSERT INTO table2 (attribute1, attribute2, attribute3, ...) VALUES(#attribute1, #attribute2, #attribute3, ...)", con))
{
cmd.Parameters.AddWithValue("#attribute1", attribute1);
cmd.Parameters.AddWithValue("#attribute2", attribute2);
cmd.Parameters.AddWithValue("#attribute3", attribute3);
....
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(result);
con.Close();
da.Dispose();
}
}
Obviously I might have a lot of attributes, so is there a simpler way to set every attribute in the table to be equal in C#?
You can use INSERT..INTO..SELECT
DataTable result = new DataTable();
using (SqlConnection con = new SqlConnection("user id=user_2;password=pwd;server=serverstring;Trusted_Connection=yes;database=database;connection timeout=30"))
{
using (SqlCommand cmd = new SqlCommand(#"INSERT INTO table2 (attribute1, attribute2, attribute3, ...)
SELECT attribute1, attribute2, attribute3 ... FROM table1
WHERE parameter=#identifying_parameter
", con))
{
cmd.Parameters.AddWithValue("#identifying_parameter", "example");
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(result);
con.Close();
da.Dispose();
}
}
You can use * instead of specifying the column name, although which is not good practice..
In order to make a second Table identical (or "equivalent" as per your definition) to the first one (for certainty let's call it sourceTable), you can use SqlBulkCopy.WriteToServer Method (DataTable)(re: https://msdn.microsoft.com/en-us/library/ex21zs8x%28v=vs.110%29.aspx)
using (SqlConnection YourConnection= new SqlConnection(YourConnectionString))
{
YourConnection.Open();
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(YourConnection))
{
bulkCopy.DestinationTableName = "dbo.YourDestinationTable";
try
{
// Write from the source to the destination.
bulkCopy.WriteToServer(sourceTable);
}
catch (Exception ex) { }
}
}
In order to get a sourceTable you can use the following code snippet:
DataTable sourceTable = SqlReadDB(YourConnString, "SELECT *")
private static DataTable SqlReadDB(string ConnString, string SQL)
{
DataTable _dt;
try
{
using (SqlConnection _connSql = new SqlConnection(ConnString))
{
using (SqlCommand _commandl = new SqlCommand(SQL, _connSql))
{
_commandSql.CommandType = CommandType.Text;
_connSql.Open();
using (SqlCeDataReader _dataReaderSql = _commandSql.ExecuteReader(CommandBehavior.CloseConnection))
{
_dt = new DataTable();
_dt.Load(_dataReaderSqlCe);
_dataReaderSql.Close();
}
}
_connSqlCe.Close();
return _dt;
}
}
catch { return null; }
}
}
Hope this may help.
I have an object below:
public class DatabaseAccess
{
private static string sConnStr;
private static SqlConnection sqlConn;
private static string ConnectionString
{
get
{
if (String.IsNullOrEmpty(sConnStr))
{
sConnStr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
}
return sConnStr;
}
}
public static int OpenConnection
{
get
{
sqlConn = new SqlConnection(ConnectionString);
return 0;
}
}
public static SqlConnection Connection
{
get
{
if (sqlConn.State != ConnectionState.Open)
{
sqlConn = new SqlConnection(ConnectionString);
sqlConn.Open();
}
return sqlConn;
}
}
}
So whenever I need a connection in my web application, I use something like:
DataTable dt = new DataTable();
using (SqlConnection cnn = DatabaseAccess.Connection)
{
using (SqlDataAdapter da = new SqlDataAdapter("MyAStoredProcedure", cnn))
{
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.Fill(dt);
}
}
return dt;
It all seems well except when there are 2 users running the codes at the same time, I will get in my web application the following error:
There is already an open DataReader associated with this Command needs to be Closed.
I need some advice how do I resolve the above issue?
Thank you.
That's because you're sharing connection objects - don't do that. DatabaseAccess.Connection should create a new SqlConnection every time.
Try to create a new instance of SqlConnection in the using statement
DataTable dt = new DataTable();
using (SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
cnn.Open();
using (SqlDataAdapter da = new SqlDataAdapter("MyAStoredProcedure", cnn))
{
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.Fill(dt);
}
}
return dt;
I'm trying to present query results, but I keep getting a blank data grid.
It's like the data itself is not visible
Here is my code:
private void Employee_Report_Load(object sender, EventArgs e)
{
string select = "SELECT * FROM tblEmployee";
Connection c = new Connection();
SqlDataAdapter dataAdapter = new SqlDataAdapter(select, c.con); //c.con is the connection string
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter);
DataTable table = new DataTable();
table.Locale = System.Globalization.CultureInfo.InvariantCulture;
dataAdapter.Fill(table);
bindingSource1.DataSource = table;
dataGridView1.ReadOnly = true;
dataGridView1.DataSource = bindingSource1;
}
What's wrong with this code?
Here's your code fixed up. Next forget bindingsource
var select = "SELECT * FROM tblEmployee";
var c = new SqlConnection(yourConnectionString); // Your Connection String here
var dataAdapter = new SqlDataAdapter(select, c);
var commandBuilder = new SqlCommandBuilder(dataAdapter);
var ds = new DataSet();
dataAdapter.Fill(ds);
dataGridView1.ReadOnly = true;
dataGridView1.DataSource = ds.Tables[0];
String strConnection = Properties.Settings.Default.BooksConnectionString;
SqlConnection con = new SqlConnection(strConnection);
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.Connection = con;
sqlCmd.CommandType = CommandType.Text;
sqlCmd.CommandText = "Select * from titles";
SqlDataAdapter sqlDataAdap = new SqlDataAdapter(sqlCmd);
DataTable dtRecord = new DataTable();
sqlDataAdap.Fill(dtRecord);
dataGridView1.DataSource = dtRecord;
You don't need bindingSource1
Just set dataGridView1.DataSource = table;
Try binding your DataGridView to the DefaultView of the DataTable:
dataGridView1.DataSource = table.DefaultView;
This is suppose to be the safest and error pron query :
public void Load_Data()
{
using (SqlConnection connection = new SqlConnection(DatabaseServices.connectionString)) //use your connection string here
{
var bindingSource = new BindingSource();
string fetachSlidesRecentSQL = "select top (50) * from dbo.slides order by created_date desc";
using (SqlDataAdapter dataAdapter = new SqlDataAdapter(fetachSlidesRecentSQL, connection))
{
try
{
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter);
DataTable table = new DataTable();
dataAdapter.Fill(table);
bindingSource.DataSource = table;
recent_slides_grd_view.ReadOnly = true;
recent_slides_grd_view.DataSource = bindingSource;
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message.ToString(), "ERROR Loading");
}
finally
{
connection.Close();
}
}
}
}
You may get a blank data grid if you set the data Source to a Dataset that you added to the form but is not being used. Set this to None if you are programatically setting your dataSource based on the above codes.
You may try this sample, and always check your Connection String, you can use this example with or with out bindingsource you can load the data to datagridview.
private void Employee_Report_Load(object sender, EventArgs e)
{
var table = new DataTable();
var connection = "ConnectionString";
using (var con = new SqlConnection { ConnectionString = connection })
{
using (var command = new SqlCommand { Connection = con })
{
if (con.State == ConnectionState.Open)
{
con.Close();
}
con.Open();
try
{
command.CommandText = #"SELECT * FROM tblEmployee";
table.Load(command.ExecuteReader());
bindingSource1.DataSource = table;
dataGridView1.ReadOnly = true;
dataGridView1.DataSource = bindingSource1;
}
catch(SqlException ex)
{
MessageBox.Show(ex.Message + " sql query error.");
}
}
}
}
you have to add the property Tables to the DataGridView Data Source
dataGridView1.DataSource = table.Tables[0];
if you are using mysql this code you can use.
string con = "SERVER=localhost; user id=root; password=; database=databasename";
private void loaddata()
{
MySqlConnection connect = new MySqlConnection(con);
connect.Open();
try
{
MySqlCommand cmd = connect.CreateCommand();
cmd.CommandText = "SELECT * FROM DATA1";
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
datagrid.DataSource = dt;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Years late but here's the simplest for others in case.
String connectionString = #"Data Source=LOCALHOST;Initial Catalog=DB;Integrated Security=true";
SqlConnection cnn = new SqlConnection(connectionString);
SqlDataAdapter sda = new SqlDataAdapter("SELECT * FROM tblEmployee;", cnn);
DataTable data = new DataTable();
sda.Fill(data);
DataGridView1.DataSource = data;
Using DataSet is not necessary and DataTable should be good enough. SQLCommandBuilder is unnecessary either.
I think this professional way to Write from start, but you can use this code with MySQL bout I think they both are the same:
1/
using System.Data; AND using MySql.Data.MySqlClient;
2/
MySqlConnection con = new MySqlConnection("datasource=172.16.2.104;port=3306;server=localhost;database=DB_Name=root;password=DB_Password;sslmode=none;charset=utf8;");
MySqlCommand cmd = new MySqlCommand();
3/
public void SetCommand(string SQL)
{
cmd.Connection = con;
cmd.CommandText = SQL;
}
private void FillGrid()
{
SetCommand("SELECT * FROM `transport_db`ORDER BY `id` DESC LIMIT 15");
DataTable tbl = new DataTable();
tbl.Load(cmd.ExecuteReader());
dataGridView1.DataSource = tbl;
}
for oracle:
var connString = new ConfigurationBuilder().AddJsonFile("AppSettings.json").Build()["ConnectionString"];
OracleConnection connection = new OracleConnection();
connection.ConnectionString = connString;
connection.Open();
var dataAdapter = new OracleDataAdapter("SELECT * FROM TABLE", connection);
var dataSet = new DataSet();
dataAdapter.Fill(dataSet);
I am working on a huge set of data, and using CLR for processing it. The CLR processing is working quick, but I need a quick way to move the processed data to the database(through CLR).
For example, see the following clr code
protected static string Normalize(string s) // space and special character remover
{
char[] arr = s.ToCharArray();
arr = Array.FindAll<char>(arr, (c => char.IsLetterOrDigit(c)));
return new string(arr).ToLower();
}
[Microsoft.SqlServer.Server.SqlProcedure]
public static void udpNormStr ()
{
SqlConnection con = new SqlConnection("context connection = true");
SqlCommand cmd = new SqlCommand("Select cName from NamesTable", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
DataTable fill = new DataTable();
fill.Columns.Add("NormName", typeof(string));
da.Fill(dt);
cmd.CommandText = "insert into NormTable values (#nName)";
cmd.Parameters.Add("#nName", SqlDbType.VarChar);
foreach (DataRow row in dt.Rows)
{
fill.Rows.Add(Normalize(row[0].ToString()));
}
con.Open();
foreach (DataRow row in fill.Rows)
{
cmd.Parameters["#nName"].Value = row[0];
cmd.ExecuteNonQuery();
}
con.Close();
}
It is taking lot of time to execute, and is wasting 90% of that time in the insert operations.
Please suggest a better way of moving processed data to database(through CLR).
SqlBulkCopy; since you have a DataTable already, you can use:
using (var bcp = new SqlBulkCopy(con))
{
bcp.DestinationTableName = "NormTable";
bcp.WriteToServer(dt);
}
Note that for streaming data, you can also create a custom IDataReader implementation and feed that to WriteToServer.
Wrap your connection with a SqlTransaction to avoid implicit transactions.
con = new SqlConnection("context connection=true");
con.Open();
using (con)
{
using (var sqlTrans = con.BeginTransaction()) //one transaction instead of many from each insert implicit
{
const string cmdText = #"INSERT INTO [table1] ([a],[b],[c],[d],[e]) VALUES (#a,#b,#c,#d,#e)";
using (var cmd = new SqlCommand(cmdText, con, sqlTrans))
{
var aField = cmd.Parameters.Add("#a", SqlDbType.NVarChar, 255);
var bField = cmd.Parameters.Add("#b", SqlDbType.Int);
var cField = cmd.Parameters.Add("#c", SqlDbType.Bit);
var dField = cmd.Parameters.Add("#d", SqlDbType.NVarChar, 255);
var eField = cmd.Parameters.Add("#e", SqlDbType.Int);
//same for all
cField.Value = false;
dField.Value = "d";
eField.Value = 1;
foreach (var someValue in valueCollection)
{
aField.Value = someValue.Key;
bField.Value = someValue.Value;
cmd.ExecuteNonQuery();
}
}
sqlTrans.Commit();
}
con.Close();
}
If this work is SQL/CLR, then that is tricky. One idea might be to make that method only return the data, for example as a CLR Table-Valued Function, and then do the INSERT back in TSQL pulling from the table-valued function.
Try to use SQLBulkCopy Class
this is sample method to Inset DataTable to Database in one Shot
public static bool SaveDetails(DataTable dbTable)
{
try
{
SqlConnection conn = new SqlConnection("Data Source=akshay;Initial Catalog=CosmosDB;User Id=sa;Password=Nttdata123");
conn.Open();
SqlBulkCopy sbc = new SqlBulkCopy(conn);
if (dbTable.Rows.Count > 0)
{
sbc.DestinationTableName = "Employee";
sbc.WriteToServer(dbTable);
}
sbc.Close();
conn.Close();
return true;
}
catch (Exception exp)
{
return false;
}
}
I am using the below code to access the MS Access Database. But i got a error message Fill: SelectCommand.Connection property has not been initialized.How can i solve this issue.
common.cs
=========
public static bool DBConnectionStatus()
{
try
{
string conString = #"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|db_admin.mdb; Jet OLEDB:Database Password=admin";
using (OleDbConnection conn = new OleDbConnection(conString))
{
conn.Open();
return (conn.State == ConnectionState.Open);
}
}
catch (OleDbException)
{
return false;
}
protected void btn_general_Click(object sender, EventArgs e)
{
try
{
bool state = common.DBConnectionStatus();
if (state == true)
{
cmd = new OleDbCommand("select * from tbl_admin");
da = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds); // Error Here
if (ds.Tables[0].Rows.Count > 0)
{
}
}
}
catch (Exception e1)
{
}
}
I did suggest you to modify your code to something like this:
private DataTable YourData()
{
string conString = #"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|db_admin.mdb; Jet OLEDB:Database Password=admin";
DataSet ds = new DataSet();
using (SqlConnection conn = new SqlConnection(conString))
{
try
{
conn.Open();
SqlCommand command = new SqlCommand("select * from tbl_admin", conn);
command.CommandType = CommandType.Text;
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
// do somethign here
}
}
catch (Exception)
{
/*Handle error*/
}
}
return ds.Tables[0];
}
And then:
protected void btn_general_Click(object sender, EventArgs e)
{
this.YourData(); // you will get the Data here. you can then use it the way you want it
}
You are initializing a Command which you use to construct a DataAdapter, but both without setting the required Connection property:
cmd = new OleDbCommand("select * from tbl_admin"); // <-- no connectuion assigned
da = new OleDbDataAdapter(cmd); // <-- no connectuion assigned
So your exception is pretty self-explanatory.
One final note: using will dispose/close the connection, so the method DBConnectionStatus is pointless. So don't use it, instead use the using in in the first place:
try
{
using(var con = new OleDbConnection(connectionString))
using(var da = new OleDbDataAdapter("elect * from tbl_admin", con))
{
var table = new DataTable();
da.Fill(table); // note that you don't need to open the connection with DataAdapter.Fill
if (table.Rows.Count > 0)
{
// ...
}
}
}
catch (Exception e1)
{
// don't catch an exception if you don't handle it in a useful way(at least loggging)
throw;
}
As per your requirement you can also use SqlDataAdapter instand of ExecuteReader.
public void ReadMyData(string connectionString)
{
string queryString = "SELECT OrderID, CustomerID FROM Orders";
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
OleDbCommand command = new OleDbCommand(queryString, connection);
connection.Open();
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(reader.GetInt32(0) + ", " + reader.GetString(1));
}
// always call Close when done reading.
reader.Close();
}
}