I have a dataGridView that displays data from a table, after I export these data as a xml file, I add the unique field to another table so I can display only non-exported data.
How I display only data that are not yet exported :
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
SqlCommand queryLocal = new SqlCommand("SELECT *uniqueField* FROM myTable
WHERE *uniqueField* = " + dataGridView1.Rows[i].Cells[3].Value.ToString().Trim().Replace("'","''"), con);
var reader = queryLocal.ExecuteReader();
if (reader.Read())
{
dataGridView1.Rows.RemoveAt(i);
i--;
}
reader.Close();
}
The problem is that it takes more than 20 seconds to filter less than 400 rows.
How could I improve the performance here ?
You could try this:
SqlCommand queryLocal = new SqlCommand("SELECT DISTINCT *uniqueField* FROM myTable");
var reader = queryLocal.ExecuteReader();
List<string> uniqueFields = new List<string>();
while (reader.Read())
uniqueFields.Add(reader[0]);
reader.Close();
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
if (uniqueFields.Contains(dataGridView1.Rows[i])
{
dataGridView1.Rows.RemoveAt(i);
i--;
}
}
Related
Let's say the following code returns the entire result row:
using (SqlCommand cmdMessages = new SqlCommand("SELECT * FROM Email where Sender = #usernameLog", conn))
{
cmdMessages.Parameters.Add(new SqlParameter("#usernameLog", Sender));
using (SqlDataReader reader = cmdMessages.ExecuteReader())
{
while (reader.Read())
{
Console.Write(); // Receiver's Name which comes from database
Console.Write();// The message which comes from same row as the receiver's name
}
}
}
The query works fine in SQL Server.
Output from SQL Server:
User hi
I want to have the same output in console.
If you just want to display the values you are retreiving as you are iterating through the datareader, you can simply do this:
using (SqlCommand cmdMessages = new SqlCommand("SELECT * FROM Email where Sender = #usernameLog", conn))
{
cmdMessages.Parameters.Add(new SqlParameter("#usernameLog", Sender));
using (SqlDataReader reader = cmdMessages.ExecuteReader())
{
int count = reader.FieldCount;
while (reader.Read())
{
for(int i = 0 ; i < count ; i++)
{
Console.WriteLine(reader.GetValue(i));
}
}
}
}
Use int count = reader.FieldCount; to count the number of fields you are returning. Then you are going to iterate through with a for statement.
If you only have 2 values you want to be displayed, you can simply replace the for with:
Console.WriteLine(reader.GetValue(0) + " " + reader.GetValue(1));
to get column values you need:
while (reader.Read())
{
reader.GetString(1);
reader.Getstring(2);
}
or
reader.GetString("ColumnName1");
reader.GetString("ColumnName2");
i load and add to my local database 700 json webpages like this :
private static Api.Root LoadJsonPages(int PageNbr)
{
Uri url = new Uri("www.website.com//page=" + PageNbr);
string info = new WebClient().DownloadString(url);
result = JsonConvert.DeserializeObject<Api.Root>(info);
return result;
}
private void LoadandAdd()
{
Api.Root result = new Api.Root();
cn.Open();
for (int i = 0; i < 700; i++)
{
result = LoadJsonPages(i);
for(int j = 0; j < result.NbrObject; j++)
{
StringBuilder sqlStr = new StringBuilder("INSERT into MyDatatable values (#Data1, #Data2, #Data3)");
SqlCommand cmd = new SqlCommand(sqlStr.ToString(), cn);
cmd.Parameters.Add(new SqlParameter("#Data1", result.items[j].Data1.value.ToString()));
cmd.Parameters.Add(new SqlParameter("#Data2", result.items[j].Data2.value.ToString()));
cmd.Parameters.Add(new SqlParameter("#Data3", result.items[j].Data3.value.ToString()));
cmd.ExecuteNonQuery();
}
}
cn.Close();
}
This code working but very slow, it takes 20mn to perform this (700 pages / 17500 objects = 25 objects/pages)
Separately load 700 pages and deserialize takes 10mn and Add it to database 10mn
how i can do it faster ?
I have a MySQL database with about 40 rows.
I want to read "value" each into its own textbox.
What I have so far
using (var cmd2 = new OdbcCommand("select value,entity_id,store_id from catalog_category_entity_varchar where attribute_id = 41 ", con))
{
con.Open();
using (var reader = cmd2.ExecuteReader())
{
while (reader.HasRows)
{
int count = reader.FieldCount;
for (int i = 0; i < count; i++)
{
while (reader.Read())
{
textBox[i].txt = (reader[0].ToString());
this.Controls.Add(textBox[i].txt);
reader.NextResult();
}
}
}
I only get the first record into a textbox.
Assume that the amount of rows is unknown.
If there is 40 rows, there must be 40 textboxes.
I've edited my code to:
using (var reader = cmd2.ExecuteReader())
{
int i = 0;
while (reader.HasRows)
{
TextBox txt = new TextBox();
txt.Text = reader.GetString(0);
this.Controls.Add(txt);
textBox[i].txt = (reader.GetString(0));
this.Controls.Add(textBox[i].txt);
reader.NextResult();
i++;
}
}
The error that I get is : error - the name textbox does not exist in the current context
If your textBox is an array of controls
con.Open(); -- you need open the connection before the command
using (var cmd2 = new OdbcCommand("select value,entity_id,store_id
from catalog_category_entity_varchar
where attribute_id = 41 ", con))
{
using (var reader = cmd2.ExecuteReader())
{
int i = 0;
while (reader.Read())
{
TextBox txt = new TextBox();
txt.Text = reader.GetString(0);
txt.Location.x = 100;
txt.Location.y = 100 * i;
this.Controls.Add(txt);
i++;
}
If you havent create the textbox already you need
TextBox txt = new TextBox();
txt.Text = reader.GetValue(0);
txt.Location.x = 100;
txt.Location.y = 100 * i;
this.Controls.Add(txt);
I have the following code . I can extract all data from all data existing in sheets in a workbook and the name of the sheet
foreach (var sheetName in GetExcelSheetNames(connectionString))
{
using (OleDbConnection con = new OleDbConnection(connectionString))
{
var dataTable = new DataTable();
string query = string.Format("SELECT {0} as sheetName, * FROM [{0}]", sheetName);
con.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter(query, con);
adapter.Fill(dataTable);
ds.Tables.Add(dataTable);
}
}
Then I write the following code to store data in a table in sql server
if (ds.Tables.Count > 0)
{
foreach (DataTable dt in ds.Tables)
{
using (SqlConnection con = new SqlConnection(consString))
{
con.Open();
for (int i = 2; i < dt.Rows.Count; i++)
{
for (int j = 1; j < dt.Columns.Count; j += 3)
{
//Here the problem
SqlCommand command = new SqlCommand( what should I write? ) ;
command.ExecuteNonQuery();
}
}
con.Close();
}
}
My problem is how to store sheetname in a table [Obj CA]?
I think your
"...VALUES('sheetname" + dt.Rows[0][j].ToString() + "' )
should be
"...VALUES('sheetname', '" + dt.Rows[0][j].ToString() + "' )
since you try to insert two values but you didn't seperate them with a comma.
But as a better way, use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
var command = new SqlCommand(#"INSERT INTO [Obj CA] (sheetname, [Rayon])
VALUES('sheetname', #rayon"), con);
for (int i = 2; i < dt.Rows.Count; i++)
{
for (int j = 1; j < dt.Columns.Count; j += 3)
{
command.Parameters.Clear();
command.Parameters.AddWithValue("#rayon", dt.Rows[0][j].ToString());
command.ExecuteNonQuery();
}
}
By the way, since I didn't know your column types, I used AddWithValue as an example but you don't. This method may generate unexpected results sometimes. Use Add overload to specify your parameter type and it's size.
Also I strongly suspect you should change your column definition order as well like (sheetname, [Rayon]) in your INSERT statement.
For some reason when I try to read in numbers from an Access database using this code, I just get blank entries in my data grid. I can read strings in fine. Anyone know why this may be? And yes, the actual data type for the unread entries in Access is a NUMBER.
string strProvider = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Employees.mdb";
string strSql = "SELECT * FROM tbl_employees";
OleDbConnection con = new OleDbConnection(strProvider);
OleDbCommand cmd = new OleDbCommand(strSql, con);
con.Open();
cmd.CommandType = CommandType.Text;
OleDbDataReader dr = cmd.ExecuteReader();
int columnCount = dr.FieldCount;
for (int i = 0; i < columnCount; i++)
{
dgv.Columns.Add(dr.GetName(i).ToString(), dr.GetName(i).ToString());
}
string[] rowData = new string[columnCount];
while (dr.Read())
{
for (int k = 0; k < columnCount; k++)
{
if (dr.GetFieldType(k).ToString() =="System.Int32")
{
rowData[k] = dr.GetInt32(k).ToString();
}
if (dr.GetFieldType(k).ToString() == "System.String")
{
rowData[k] = dr.GetString(k);
}
}
dgv.Rows.Add(rowData);
}
I suggest you try stepping through your code in the debugger so you can see what's happening. My first guess would be that your numeric fields aren't returned as Int32, perhaps they are floats or decimals instead.
If for some reason you can't step through it, try something like this:
if (dr.GetFieldType(k).ToString() =="System.Int32")
{
rowData[k] = dr.GetInt32(k).ToString();
}
else if (dr.GetFieldType(k).ToString() == "System.String")
{
rowData[k] = dr.GetString(k);
}
else
{
rowData[k] = dr.GetFieldType(k).ToString();
}
That will let you see what type of value is in the fields that didn't get displayed.