I understand that with PHP I can use mysql_query($sql); and mysql_fetch_array($result); to fetch some MySQL data and place it into an array. How is this achieved in C# to where I could place my data in say, a datagrid?
This is probably the most quintessential ADO.NET code to fill DataGrid you're going to see (using disconnected DataSets, that is):
DataTable results = new DataTable();
using(MySqlConnection conn = new MySqlConnection(connString))
{
using(MySqlCommand command = new MySqlCommand(sqlQuery, conn))
{
MySqlDataAdapter adapter = new MySqlDataAdapter(command);
conn.Open();
adapter.Fill(results);
}
}
someDataGrid.DataSource = results;
someDataGrid.DataBind();
Related
I have a dataGridView that loads its data from an SQL server with the Data Source utility:
However when I trigger the following code:
using (var conn = new SqlConnection(connectionString))
{
string sql = "SELECT * FROM AssetManagement_copy";
using (var cmd = new SqlCommand(sql, conn))
{
sda = new SqlDataAdapter(cmd);
sda.Fill(filteredTable);
dataGridView1.DataSource = filteredTable;
}
}
The Serial No. column of the dataGridView loses its data?
Any ideas as to why this might be happening? I don't do any specific column manipulation or specify any dataColumn in the code to do anything with.
Thanks all!
Good day sir and ma'am. I'm planning to get all row header like "column_id and first_name, last_name and so on" and populate my listbox with row header from mysql database table. Please enlighten me how to do this. I am not sure what to use MySqlDataAdapter or MySqlDataReader. I'm beginner and willing to learn.
using (MySqlConnection conns2 = new MySqlConnection(connString))
{
conns2.Open();
MySqlCommand comm2 = new MySqlCommand("SELECT * FROM table1",
conns2);
MySqlDataAdapter add2 = new MySqlDataAdapter(comm2);
DataTable dt2 = new DataTable();
add2.Fill(dt2);
foreach(DataColumn column in dt2.Columns)
{
columnlistbox.Items.Add(dt2.Columns);
//it shows "collection" and exactly the number of row header
//but it doesn't show like "First name, client_id and last
//name"
}
conns2.Close();
}
for get columns names from a DataTable
If you need data from the db, and you load it into a DataTable (using DbDataAdapter or DbDataReader), you can know the column names from the DataTable.Columns collection property:
foreach (DataColumn col in dt2.Columns)
columnlistbox.Items.Add(col.ColumnName);
get only schema from MySql db (tables, columns ect)
but if you not need any data from the DB, but only its structure, you can use the DbDataReader. for load this data by the reader, a query must be "simulated" to the database:
using (MySqlConnection conns2 = new MySqlConnection(connString))
{
conns2.Open();
MySqlCommand comm2 = new MySqlCommand("SELECT * FROM table1", conns2);
using (var reader = MySqlCommand.ExecuteReader(CommandBehavior.SchemaOnly))
{
reader.Read();
var dtSchema = reader.GetSchemaTable();
foreach (DataRow row in tableSchema.Rows)
columnlistbox.Items.Add(row["ColumnName"]);
}
}
form https://stackoverflow.com/a/7159610/1271037:
Using the MySqlDataAdapter is the appropriate choice based on the sample code you provided because you are populating a DataTable and in ADO.NET DataAdapters are traditionally used to populate DataTables. A DataAdapter populates or "fills" your DataTable object.
You could also use a DataReader to populate your DataTable:
var dataReader = cmd.ExecuteReader();
var dataTable = new DataTable();
dataTable.Load(dataReader);
DataAdapters and DataReaders are a core design concept of ADO.NET, whether using Sql Server or MySQL database. A DataReader is a forward only, light and faster Database query helper. A DataAdapter is a bit heavier than a DataReader and also does more than a DataReader can do, it is possible that a DataAdapter uses a DataReader behind the scenes.
Here is how you would use the data from your MySQL database, you need to use a DataGrid, not a ListBox
using (MySqlConnection conn = new MySqlConnection(connString))
{
conn.Open();
MySqlCommand cmd = new MySqlCommand("SELECT * FROM table1",
conn);
MySqlDataAdapter adapter = new MySqlDataAdapter(cmd);
DataTable dt = new DataTable();
adapter.Fill(dt);
//display your dataset in a ASP.NET Web Forms DataGrid
dataGrid.DataSource = dt;
dataGrid.DataBind();
//conn.Close();// you do not need this, your using statements call Dispose and Dispose will release the connection back to the connection pool
}
You can get pointers from this code. In summary GetName is what you are looking for.
using (Common.DbCommand cmd = conn.CreateCommand()) {
cmd.CommandText = "SELECT * FROM table1";
dynamic dr = cmd.ExecuteReader();
int index = 0;
List<string> columns = new List<string>();
for (index = 0; index <= dr.FieldCount - 1; index++) {
columns.Add(dr.GetName(index));
}
}
What would be the best way of building an empty DataTable based on existing table in SQL server? My current try is this one, which is just retyping this manually, so it is not great, especially for large data sets.
private DataTable createEmptyReadingDataTableReadyToSaveToDb()
{
dtbl.Columns.Add("ProductId", typeof(string));
dtbl.Columns.Add("Price", typeof(float));
dtbl.Columns.Add("Revenue", typeof(float));
dtbl.Columns.Add("URL", typeof(string));
// etc ....
return dtbl;
}
I read today about schemas, which seem natural for this task. It got me more confused than I thought this would be. Anyways such approach below returns a datatable returning broad set of information about the dataset, but I do not find there accessors to get information about the interesting DataTable (below). Probably I do something wrong.
private static DataTable getReadingTableFromSchema()
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalDbConnnectionString"].ConnectionString))
{
string sql = "SELECT * FROM [Readings]";
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader reader = cmd.ExecuteReader();
DataTable dtbl = reader.GetSchemaTable();
return dtbl;
}
}
I could also just try the approach with DataAdapter reading the data, then filling it (basically copying the DataTable) and then deleting all rows to have the table empty - but this would definitely affect the performance. What would be the right solution?
you can use DataAdapter and fill DataTable with full schema:
private static DataTable getReadingTableFromSchema()
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalDbConnnectionString"].ConnectionString))
{
string sql = "SELECT * FROM [Readings]";
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
DbDataAdapter da = new SqlDataAdapter(cmd);
DataTable dtbl = new DataTable();
da.FillSchema(dtbl, SchemaType.Source);
return dtbl;
}
}
And, I suggest you to use "using" for command and adapter too
Using a bit of LINQ
using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalDbConnnectionString"].ConnectionString))
{
conn.Open();
using (var reader = new SqlCommand("SELECT * FROM [Readings] WHERE 1 = 0", conn).ExecuteReader())
{
var dataColumns = Enumerable.Range(0, reader.FieldCount)
.Select(i => new DataColumn(reader.GetName(i), reader.GetFieldType(i)))
.ToArray();
var dataTable = new DataTable("Readings");
dataTable.Columns.AddRange(dataColumns);
}
}
I'm trying to design a method to allow me to take a row from a SQL database using a SELECT. I then want to INSERT the returned row into an identical table on a database which resides on a different server.
My server connection and SELECT statement both work; I can view the row I want copied in a console window.
The issue I'm having is figuring out what data structure I need to use in C#, how to populate this data structure with the SELECT, and finally how to use that data structure to INSERT the row.
I'd like to keep the option for multiple rows open, but for now if I could get a single row transferring across it would be fantastic.
Thank you.
Edit: I've been able to work through this myself after a bunch of research. I've included my code below in the heop it helps someone else, but although it works, it is far from ideal. I am an amateur and it is not yet complete.
static public void CopyDatabaseRows(string ConnectionStringDEV, string ConnectionStringLOCAL, string queryString)
{
//Connect to first database table to retreive row/rows and populate dataset + datatable.
DataSet dataSet = new DataSet();
SqlConnection conn = new SqlConnection(ConnectionStringDEV);
conn.Open();
SqlCommand command = new SqlCommand(queryString, conn);
DataTable dataTable = new DataTable();
SqlDataAdapter dataAdapter = new SqlDataAdapter(queryString, conn);
dataAdapter.FillSchema(dataSet, SchemaType.Mapped);
dataAdapter.Fill(dataSet, "dbo.FileRegister");
dataTable = dataSet.Tables["dbo.FileRegister"];
conn.Close();
//Connect to second Database and Insert row/rows.
SqlConnection conn2 = new SqlConnection(ConnectionStringLOCAL);
conn2.Open();
SqlBulkCopy bulkCopy = new SqlBulkCopy(conn2);
bulkCopy.DestinationTableName = "dbo.FileRegister";
bulkCopy.WriteToServer(dataTable);
}
I'd suggest you use something like Simple.Data (https://github.com/markrendle/Simple.Data) to do this really easily. Because it uses C# dynamics, you can just load the dynamic type, and insert it directly into a second Simple.Data connection without worrying about type conversion.
Something like:
var db = Database.OpenConnection("data source=.;initial catalog=Xyz;etc");
var db2 = Database.OpenConnection("data source=somewhereElse;initial catalog=Xyz;etc");
dynamic user = db.Users.FindById(1);
db2.Users.Insert(user);
It works perfectly... I modified this code... Use it...
string local = "Server=destinationservername;Database=destinationserverdb;Uid=sa;Pwd=<Password>;
string dev = "Server=sourceservername;Database=sourceserverdb;Uid=sa;Pwd=Password;
private void btncopy_Click(object sender, EventArgs e)
{
CopyDatabaseRows(dev, local, query);
}
static public void CopyDatabaseRows(string ConnectionStringDEV, string ConnectionStringLOCAL, string queryString)
{
//Connect to first database table to retreive row/rows and populate dataset + datatable.
DataSet dataSet = new DataSet();
SqlConnection conn = new SqlConnection(ConnectionStringDEV);
conn.Open();
SqlCommand command = new SqlCommand(queryString, conn);
DataTable dataTable = new DataTable();
SqlDataAdapter dataAdapter = new SqlDataAdapter(queryString, conn);
dataAdapter.FillSchema(dataSet, SchemaType.Mapped);
dataAdapter.Fill(dataSet, "dbo.DeviceLogs");
dataTable = dataSet.Tables["dbo.DeviceLogs"];
conn.Close();
//Connect to second Database and Insert row/rows.
SqlConnection conn2 = new SqlConnection(ConnectionStringLOCAL);
conn2.Open();
SqlBulkCopy bulkCopy = new SqlBulkCopy(conn2);
bulkCopy.DestinationTableName = "dbo.DeviceLogs";
bulkCopy.WriteToServer(dataTable);
MessageBox.Show(dataTable.Rows.Count.ToString() + " rows copied successfully", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
I want to populate a gridview with table data from SQL. I tried just returning my SqlDataReader object and using it as my datasource, but I am getting errors that the reader has been closed. I wanted to convert this to a DataSet and just return a dataset, but I couldn't find an easy way to convert the row data to a dataset. I've also read that DataSets are dead in .NET 3.5/4.0, is this true?
Here's my Data Layer method. It would be awesome if I could return something useable as a datasource:
public SqlDataReader GetSites()
{
SqlConnection sqlCon = null;
SqlDataReader rdr = null;
try
{
sqlCon = new SqlConnection(StoredProcedures.conString);
sqlCon.Open();
SqlCommand cmd = new SqlCommand("GetSites", sqlCon);
cmd.CommandType = CommandType.StoredProcedure;
rdr = cmd.ExecuteReader();
return rdr;
}
finally
{
if (sqlCon != null)
{
sqlCon.Close();
}
//if (rdr != null)
//{
// rdr.Close();
//}
}
}
As Carlos Munoz has stated, you closed your sql connection. You need the SQL connection opened in order for the reader to read. Simply comment out
if (sqlCon != null)
{
sqlCon.Close();
}
and you should be fine.
Another alternative is to use SqlDataAdapter which I prefer.
Here is an example...
public static DataSet GetDataSet(string sql, DatabaseType database)
{
using ( var connection = new SqlConnection( GetConnectionString(database) ) )
{
using (var adapter = new SqlDataAdapter(sql, connection))
{
var temp = new DataSet();
adapter.Fill(temp);
return temp;
}
}
}
Just set the data source of your data grid to the Data set's table returned.
DGV.DataSource = DatabaseFunction.GetDataSet(sql, DatabaseType.Outage).Tables[0].DefaultView;
I suggest using a Typed-Dataset with typed table adapters. Add a new Typed-DataSet into your project and drop the tables from the server explorer in visual studio directly into your typed-dataset and configure it. You can then use that type dataset as the datasource of your datagrid
dataAdapter = new SqlDataAdapter(sqlQuery, DatabaseConnectionString);
SqlCommandBuilder builder = new SqlCommandBuilder(dataAdapter);
builder.GetUpdateCommand();
dataSet = new DataSet();
DataAdapter.Fill(dataSet);
dataGridView.DataSource = dataSet.Tables[0];
SqlCommandBuilder should be used if you want to update changes made in dataGridView back to SqlDatabase! Than you can write:
dataAdapter.Update(dataSet);
If you want to use new stuff, you can generate object model that corresponds to you SqlDatabase with SqlMetal tool. This will generate classes that have members as tables is your dataabse. After that you use LINQ query that is used as datasource of you dataGeidView.