Modifying a DataTable - c#

Situation:
Hello! I am trying to populate a WPF toolkit DataGrid with a MS Access database.
Here is what I have right now (it works):
//Load the datagrid with the database
private void LoadDataGrid(string filename, string path)
{
string databaseConn = "Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=" + path + "\\" + filename,
tableName ="";
OleDbConnection conn = null;
DataTable schemaTable,
table = new DataTable();
try
{
conn = new OleDbConnection(databaseConn);
try
{
conn.Open();
schemaTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,
new object[] { null, null, null, "TABLE" });
tableName = "[" + schemaTable.Rows[0].ItemArray[2].ToString() + "];";
string sqlQuery = "SELECT * FROM " + tableName;
OleDbCommand command = new OleDbCommand(sqlQuery, conn);
OleDbDataReader reader;
reader = command.ExecuteReader();
table.Load(reader);
DataGrid_.ItemsSource = table.DefaultView;
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
finally
{
conn.Close();
}
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
}
The code sample above loads a WPF toolkit DataGrid with the help of a MS Access database.
What I would like to do is be able to insert a column in the DataGrid at the very beginning. This column would be used to write the row number. What I think could work is to modify the table variable (which is a DataTable object).
Question:
So, how can I insert a column in the table variable, add the row number for each rows in that new column, and have all the data from the database in the DataGrid?

An alternative is to create a column on the DataTable before loading the IDataReader into it.
// the rest of your code
//
DataTable table = new DataTable();
DataColumn col = table.Columns.Add("RowNumber", typeof(int));
col.AutoIncrementSeed = 1;
col.AutoIncrement = true;
//
// the rest of your code
//
table.Load(reader)
//
// the rest of your code
The code snippet bellow demonstrates the technique out of the question's context
//Simulates data coming from a database or another data source
DataTable origin = new DataTable();
DataColumnCollection columns = origin.Columns;
columns.Add("Id", typeof(int));
columns.Add("Name", typeof(string));
origin.Rows.Add(55, "Foo");
origin.Rows.Add(14, "Bar");
IDataReader reader = origin.CreateDataReader();
DataTable table = new DataTable();
//Sets up your target table to include a new column for displaying row numbers
//These are the three lines that make it all happen.
DataColumn col = table.Columns.Add("RowNumber", typeof(int));
col.AutoIncrementSeed = 1;
col.AutoIncrement = true;
//Simulates loading data from the database
table.Load(reader);
// Examine table through the debugger. Is will have the contents of "origin" with the column "RowNumber" prepended

Your easiest solution would be to modify your code to include a "virtual" RowNumber field in your original SELECT query, like so:
SELECT ROWNUM AS ROWNUMBER, * FROM TABLE1
Unfortunately, Access doesn't have anything like a ROWNUM function, so I think the easiest solution is to add a RowNumber column in the SELECT query like this:
SELECT 0 AS ROWNUMBER, * FROM TABLE1
which will add a column containing all zeroes at the beginning, and then iterate through the resulting DataTable and set the row number, like this:
int rownumber = 1;
foreach (DataRow row in table.Rows)
{
row["ROWNUMBER"] = rownumber;
rownumber++;
}
and then dump the DataTable into the grid.

Related

DatagridView by SQL

I have a datagridview with 4 columns
[](https://i.stack.imgur.com/wvD94.png)
and I want to make a query in my database, so that it appears in my datagridview.
public DataTable pesquisar(string produto)
{
DataTable _dt = new DataTable();
string sqlQuery = "Select cd_produto, " +
"ds_produto, " +
"referencia, " +
"ds_marca " +
"FROM produto";
command.CommandText = sqlQuery;
try
{
command.Connection = conn.Conectar();
using (SqlDataAdapter da = new SqlDataAdapter(sqlQuery, command.Connection))
{
command.ExecuteNonQuery();
using (DataTable _DT = new DataTable())
{
da.Fill(_DT);
return _DT;
}
}
}
catch (Exception)
{
throw;
}
}
I did it like this, but this way it adds new columns to my datagrid
When you set the DataSource of a DataGridView and AutoGenerateColumns is set to true, any columns/properties in the data source that do not match existing columns will have a new column generated for them. The way you match a column that you create to a column/property in the data source is to set the grid column's DataPropertyName property. For example, if you have a column in your data source named "cd_produto" then you need to set the DataPropertyName property of the corresponding grid column to "cd_produto" and then that source column will bind to that grid column.

C# simple subtraction from two different database

I have 2 different databases - SQLite and PostgreSQL and i trying to make tiny math on table from this databases.
Both tables contains columns nr_serii and ilosc, SQLite:
And Postgres:
I established a connection to both databases and populate dataset. Maybe i should use different place to store the data?
I need to substraction column ilosc: (sqlite-postgres), but not know how to do that.
For example, for each nr_serii make substraction column ilosc:
nr_serii:222222
ilosc:15-7=8
Finally i want to show output data to datagridview.
When i use messagebox i can see the data in dataset. Here is my part of code:
string cs = #"URI = file:" + Sdatabase;
string csP = conParam;
string sqlP = "select nr_serii, ilosc from stany";
string sql = "select nr_serii, ilosc from przychod";
using var con = new SQLiteConnection(cs);
con.Open();
using var cmd = new SQLiteCommand(sql, con);
SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
using var conP = new NpgsqlConnection(csP);
conP.Open();
NpgsqlCommand cmdP = new NpgsqlCommand(sqlP, conP);
NpgsqlDataAdapter DA = new NpgsqlDataAdapter(cmdP);
DataSet dsP = new DataSet();
DA.Fill(dsP);
//----------test-----------
foreach (DataRow row in dsP.Tables[0].Rows)
{
var nr_serii = row["nr_serii"];
var ilosc = row["ilosc"];
MessageBox.Show(nr_serii +","+ ilosc);
}
//--------------------------
For example, you can browse data table from first datasource ds and search for a matching row by value of nr_serii column for each row in the datatable in second datasource dsP, and if found, add a new row with the calculation result to the new third result table.
Then you don't forget to solve the problem of what to do with records that are only in the first ds or only in the second dsP datasource, depending on the value of the nr_serii column.
Program code example:
//prepare result third DataTable
DataTable resultDt = new DataTable();
resultDt.Columns.Add("nr_serii");
resultDt.Columns.Add("ilosc");
//add content to result DataTable
foreach (DataRow row in ds.Tables[0].Rows)
{
var nr_serii = row["nr_serii"];
var ilosc = row["ilosc"];
DataRow drP = null;
foreach (DataRow dataRow in dsP.Tables[0].Rows)
{
if (nr_serii.ToString() == (string)dataRow["nr_serii"])
{
drP = dataRow;
break;
}
}
if (drP != null)
{
var dr = resultDt.NewRow();
dr["nr_serii"] = nr_serii;
dr["ilosc"] = (int)ilosc - (int)drP["ilosc"];
resultDt.Rows.Add(dr);
}
}

Store attributes by SQL in Arraylist and show on textboxes

I'm making a system where I want to take a SQL data and store in an arraylist.
Example: In the database there are the attributes (name, address, gender ...), these attributes will be stored in an arraylist and then a function will read this arraylist and print the data in the textbox (disabled).
I'm using VS C# 2010, MySQL and ODBC.
An idea: http://snag.gy/HPrny.jpg
Thanks!
I would suggest you to try to get it using DataSet:
public DataTable GetDBDataTable(MySqlConnection dbconnection, string table, string columns = "*", string clause = "")
{
MySqlCommand mysqlcmd = new MySqlCommand("SELECT " + columns + " FROM " + table + " " + clause +";", dbconnection);
MySqlDataAdapter mysqlad = new MySqlDataAdapter(mysqlcmd);
DataSet ds = new DataSet();
mysqlad.Fill(ds);
DataTable dt = ds.Tables[0];
return dt;
}
DataTable class on MSDN:
http://msdn.microsoft.com/FR-FR/library/system.data.datatable.aspx
You can easily operate data in this way :)
If you want to show each entry in a MessageBox:
foreach (DataRow row in dt.Rows)
{
int i = 0;
foreach (DataColumn column in dt.Columns)
{
MessageBox.Show(dt.row.ItemArray[i].ToString();
i++;
}
}

is C# datatable make db query several times or only for the first time?

i have a Database table.This table is not frequently changes. But i need to retrieve data from that table. i requirement is when the application start then it read all the record of that table and store it into the data Table. So, when needed that i just make query the record from data table not from the database. I already write the code. Now my question is : ** **when i call the method then is it this code query to database every time and create the DataTable every time or first fetch the data from db only once and store it into datatable until the application close?**** if not please help me to sort it out.
static void Main(string[] args)
{
String RoomNumber = GetTable("xi");
Console.WriteLine(RoomNumber);
Console.ReadLine();
}
static string GetTable(string ShortCode)
{
DataTable table = new DataTable();
DataColumn column;
DataRow row;
column = new DataColumn();
column.DataType = Type.GetType("System.String");
column.ColumnName = "Class";
table.Columns.Add(column);
column = new DataColumn();
column.DataType = Type.GetType("System.String");
column.ColumnName = "RoomNumber";
table.Columns.Add(column);
SqlConnection thisConnection = new SqlConnection(conn);
thisConnection.Open();
SqlCommand thisCommand = thisConnection.CreateCommand();
thisCommand.CommandText = "SELECT Class,RoomNumber FROM Section ";
SqlDataReader thisReader = thisCommand.ExecuteReader();
while (thisReader.Read())
{
row = table.NewRow();
row["Class"] = thisReader["Class"].ToString();
row["RoomNumber"] = thisReader["RoomNumber"].ToString();
table.Rows.Add(row);
}
thisConnection.Close();
DataRow[] result = table.Select("Class='" + Class + "'");
foreach (DataRow dataRow in result)
{
RoomNumber = dataRow[1].ToString();
//Console.WriteLine("{0}, {1}", dataRow[0], dataRow[1]);
}
//Console.WriteLine(RoomNumber);
return RoomNumber;
}
This would load the data from the database into your DataTable when the program starts, and under the assumption that you do not invoke the GetTable method any other places, it will be run only once.

Select and Insert command OLEDB Command c#

I have a excel sheet with two tabs so i want to get a row from one tab and insert into another,i thought it would be same like in sqlserver or mysql . Just select and insert..
I am using this query but it says syntax error not sure what is wrong in it.
testCommand.CommandText = "Insert into [ActiveLicenses$]( Select * from [companies$]
where [License Number] = '" + lnumber + "')";
testCommand.ExecuteNonQuery();
UPDATE
Is there any way to delete the rows directly from excel sheet?
You can use SQL to extract the data from Excel:
using (OleDbDataAdapter da = new OleDbDataAdapter(
"SELECT " + columns + " FROM [" + worksheetName + "$]", conn))
{
DataTable dt = new DataTable(tableName);
da.Fill(dt);
ds.Tables.Add(dt);
}
Unfortunately inserting into excel doesn't work this way. I am pretty sure you cant specify a cell to write to using OleDb Insert Command, it will automatically go to the next open row in the specified column. You can workaround it with an update statement:
sql = "Update [Sheet1$A1:A10] SET A10 = 'YourValue'";
myCommand.CommandText = sql;
myCommand.ExecuteNonQuery();
Personally I would use VSTO rather than oleDB. Once you have extracted the cell simply open up the spreadsheet with code and insert the data:
Excel.Workbook wb = xlApp.Workbooks.Open(filePath);
rng = wb.Range["A1"];
rng.Value2 = "data";
A faster method.
I take all the licenses into a DataTable and remove the ones not required takes less than 1 minute. and then simply export DataTable to Csv so i have the file ready in less than 1 minute.
Sample below:
static List<string> licensecAll = new List<string>();
DataTable dt = new DataTable();
OleDbDataAdapter dp = new OleDbDataAdapter("select * from [companies$]", testCnn);
dp.Fill(dt);
if (dt.Rows.Count > 0)
{
for (int i = dt.Rows.Count-1; i >= 0; i--)
{
string lnum = dt.Rows[i][0].ToString();
Console.WriteLine("LICENSE NUMBER" + lnum);
if (!licensecAll.Contains(lnum))
{
Console.WriteLine("ROW REMOVED");
dt.Rows.RemoveAt(i);
}
}
}
Then simply run datatable to csv....
public static void DataTable2CSV(DataTable table, string filename, string seperateChar)
{
StreamWriter sr = null;
try
{
sr = new StreamWriter(filename);
string seperator = "";
StringBuilder builder = new StringBuilder();
foreach (DataColumn col in table.Columns)
{
builder.Append(seperator).Append(col.ColumnName);
seperator = seperateChar;
}
sr.WriteLine(builder.ToString());
foreach (DataRow row in table.Rows)
{
seperator = "";
builder = new StringBuilder();
foreach (DataColumn col in table.Columns)
{
builder.Append(seperator).Append(row[col.ColumnName]);
seperator = seperateChar;
}
sr.WriteLine(builder.ToString());
}
}
finally
{
if (sr != null)
{
sr.Close();
}
}
}

Categories

Resources