Не делайте этого в CellContentClick
, но в обработчике SelectionChanged
. Заказы должны иметь CustomerID
, который можно использовать для фильтрации в предложении WHERE:
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (dataGridView1.CurrentRow?.DataBoundItem is Customer customer) {
var orders = new List<Order>();
using (var conn = new SqlConnection(STR_Connection))
using (var cmd = new SqlCommand("select * from Orders where CustomerID=@cid", conn)) {
cmd.Parameters.Add("@cid", SqlDbType.NChar, 5).Value = customer.CustomerID;
conn.Open();
using (SqlDataReader rdr = cmd.ExecuteReader()) {
while (rdr.Read()) {
var o = new Order {
OrderID = (int)rdr["OrderID"],
CustomerID = (string)rdr["CustomerID"],
OrderDate = (DateTime)rdr["OrderDate"],
ShipName = (string)rdr["ShipName"],
ShipCity = (string)rdr["ShipCity"],
ShipCountry = (string)rdr["ShipCountry"]
};
orders.Add(o);
}
}
}
dataGridView2.DataSource = orders;
} else {
dataGridView2.DataSource = null;
}
}
Важно передать параметры в качестве параметра команды и объединить его в командную строку SQL. Это может привести к атаке SQL-инъекции (здесь, вероятно, нет, но в общем случае ...). Это также повышает производительность запроса, поскольку SQL-сервер может кэшировать план выполнения, поскольку командная строка не изменяется для разных клиентов.
Поместите соединение, команду и читателя в операторы usingчтобы они автоматически удалялись.
Фильтрация по текстовому полю работает почти так же. Перезагрузите клиентов в событии TextChanged
или Validated
или Leave
текстового поля:
private void txtFilter_TextChanged(object sender, EventArgs e)
{
LoadCustomers(txtFilter.Text);
}
, а также в событии Load:
private void Form1_Load(object sender, EventArgs e)
{
LoadCustomers();
}
Разница между TextChanged
и два других события - это то, что первое срабатывает для каждого введенного персонажа. Чтобы другие работали, вы должны оставить текстовое поле.
Тогда вам придется обработать два случая, когда фильтр пуст или нет. Если оно пустое, либо выберите клиентов без предложения WHERE (т.е. верните все строки), либо не возвращайте строки вообще (dataGridView1.DataSource = null;
). В противном случае установите соответствующий пункт where. Возможно
WHERE CompanyName LIKE @filter OR ContactName LIKE @filter
Затем вставьте строку фильтра в %
. Это подстановочный знак в SQL.
private void LoadCustomers(string filter = null) // Optional filter parameter
{
string sql = "select * from Customers";
SqlParameter filterParameter = null;
if (!String.IsNullOrWhiteSpace(filter)) {
sql += " WHERE CompanyName LIKE @filter OR ContactName LIKE @filter";
filterParameter = new SqlParameter("@filter", SqlDbType.NVarChar) {
Value = "%" + filter + "%" // Add wildcards.
};
}
var Customers = new List<Customer>();
using (var conn = new SqlConnection(STR_Connection))
using (var cmd = new SqlCommand(sql, conn)) {
if (filterParameter != null) {
cmd.Parameters.Add(filterParameter);
}
conn.Open();
using (var rdr = cmd.ExecuteReader()) {
while (rdr.Read()) {
var c = new Customer() {
CustomerID = (string)rdr["CustomerID"],
CompanyName = (string)rdr["CompanyName"],
ContactName = (string)rdr["ContactName"],
City = (string)rdr["City"],
Country = (string)rdr["Country"],
Phone = (string)rdr["Phone"]
};
Customers.Add(c);
}
}
}
dataGridView1.DataSource = Customers;
}