我有一个richTextBox
,用户可以输入以搜索数据库,然后显示该数据库中的某些列。所有这一切都有效,但是当搜索其他内容时,它将用新的搜索覆盖第一个搜索。有没有办法不做,而是将每个搜索显示在单独的行中?
这是我有沙发的代码
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection();
conn.ConnectionString = @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\DBaddMat.mdf;Integrated Security=True";
conn.Open();
SqlDataAdapter adapter = new SqlDataAdapter("SELECT GetDate() as Event, Owner, Holder, MAT, Location FROM TBLMat where MAT like '%" + richTextBox1.Text + "%'", conn);
DataTable dt = new DataTable();
adapter.Fill(dt);
mainAMSDataGrid.DataSource = dt;
mainAMSDataGrid.Visible = true;
conn.Close();
}
}
添加mainAMSDataGrid.Rows.Add();
时,它会崩溃并出现错误
System.InvalidOperationException: 'Rows cannot be programmatically added to the DataGridView's rows collection when the control is data-bound.'
我已经在寻找一种解决方案,但是可以找到一个用户实际搜索数据库的地方,就像我想要达到的目标。
谢谢
答案 0 :(得分:0)
首先,为变量指定描述性名称:richTextBoxSearch
而不是richTextBox1
,依此类推。
第二,使用参数来防止sql注入。
第三,使用using
。
第四,将DataTable
设为类(窗体)字段,而不是局部变量。
DataTable dataTable = new DataTable(); // field
因此,代码可能如下所示:
private void RichTextBoxSearch_TextChanged(object sender, EventArgs e)
{
using (var conn = new SqlConnection())
{
conn.ConnectionString = @"...";
conn.Open();
// Note the @search parameter.
using (var adapter = new SqlDataAdapter(
"SELECT ... FROM TBLMat where MAT like @search", conn))
{
// Use the type of SqlDbType that you have in the database table
adapter.SelectCommand.Parameters.Add("search", SqlDbType.NVarChar).Value =
"%" + richTextBoxSearch.Text + "%";
adapter.Fill(dataTable); // note that the dataTable is NOT a local variable
if (dataTable.Columns.Count > 0)
{
// It is assumed that Columns[0] contains unique values
dataTable.PrimaryKey = new DataColumn[] { dataTable.Columns[0] };
}
mainAMSDataGrid.DataSource = dataTable;
mainAMSDataGrid.Visible = true;
}
}
}
需要使用if
语句中的代码来防止重复。如果不需要,可以将其删除。
对于主键,指定包含唯一值的列。通常是id。