我通过以下方法将DataTable绑定到DGV:
public DataTable GetDgvData(string selectQuery, string companyFilter, string categoryFilter, string idFilter)
{
using (NpgsqlConnection conn = new NpgsqlConnection(connString))
using (NpgsqlCommand cmd = new NpgsqlCommand(selectQuery, conn))
{
cmd.Parameters.Add(new NpgsqlParameter("company", companyFilter));
if (!string.IsNullOrEmpty(idFilter)) cmd.Parameters.Add(new NpgsqlParameter("idList", idFilter));
if (categoryFilter != "All Categories") cmd.Parameters.Add(new NpgsqlParameter("category", categoryFilter));
DataSet ds = new DataSet();
conn.Open();
using (NpgsqlDataAdapter da = new NpgsqlDataAdapter(cmd))
{
da.Fill(ds);
}
conn.Close();
return ds.Tables[0];
}
}
最初,它没有最后一个参数string idFilter
或第二个cmd.Parameters.Add() line
。而且对该方法的所有调用都运行良好,并填充了使用该方法的DGV。
然后我向WinForm中添加了搜索功能,该功能在DGV的DataTable中搜索用户输入的字符串,遍历DataTable,为具有搜索字符串的行建立记录ID的列表,然后我需要仅使用在DataTable的单元格中具有搜索字符串的行来重建DGV。
这是该搜索过程的功能:
private void btnSearch_Click(object sender, EventArgs e)
{
string searchText = txtSearchCatsGrid.Text;
string idToAddToList = "";
string tempIdList = "";
string idListForQuery = "";
DataTable dt = ((DataTable)dgvCategories.DataSource);
string cellValue;
int rowIndex;
int columnIndex;
for (rowIndex = 0; rowIndex <= dt.Rows.Count - 1; rowIndex++)
{
for (columnIndex = 0; columnIndex <= dt.Columns.Count - 1; columnIndex++)
{
cellValue = dt.Rows[rowIndex][columnIndex].ToString();
if (searchText == cellValue)
{
// Set corresponding dgvCategories cell's background color to yellow
dgvCategories[columnIndex, rowIndex].Style.BackColor = Color.Yellow;
idToAddToList = dt.Rows[rowIndex][0].ToString();
}
}
if (!string.IsNullOrEmpty(idToAddToList) && !tempIdList.Contains(idToAddToList)) tempIdList += idToAddToList + ",";
}
if (!string.IsNullOrEmpty(tempIdList))
{
idListForQuery = tempIdList.Remove(tempIdList.Length - 1, 1);
}
Console.WriteLine("idListForQuery: " + idListForQuery);
// Refresh dgvCategories with just rows from search, using idListForQuery
string companyFilter = cboSelectCompany.Text;
string categoryFilter = cboSelectCategory.Text;
db categoriesData = new db();
if (categoryFilter == "All Categories")
{
string catsQuery = "SELECT id, category, source_company, old_value, old_desc, new_value, new_desc, reference1, reference2 " +
"FROM masterfiles.xref"+
" WHERE company_name = @company" +
" AND id IN (@idList)" +
" ORDER BY category, old_value, source_company";
this.dtCategories = categoriesData.GetDgvData(catsQuery, companyFilter, categoryFilter, idListForQuery);
}
else
{
string catsQuery = "SELECT id, category, source_company, old_value, old_desc, new_value, new_desc, reference1, reference2 " +
"FROM masterfiles.xref" +
" WHERE company_name = @company" +
" AND category = @category" +
" AND id IN (@idList)" +
" ORDER BY old_value, source_company";
this.dtCategories = categoriesData.GetDgvData(catsQuery, companyFilter, categoryFilter, idListForQuery);
}
// TODO: Need to check this.dtCategories.Rows.Count
dgvCategories.DataSource = this.dtCategories;
if (dtCategories.Rows.Count == 0)
{
return;
}
else
{
dgvCategories.Columns[0].Visible = false;
dgvCategories.Rows[0].Cells[0].Selected = false;
}
}
传递给GetDgvData()
函数的ID列表是正确的,据我所知,其实现与公司和类别过滤器完全相同。加载表单并初始填充DGV时,程序运行正常(我将空字符串传递给GetDgvData()
,以进行其他所有调用),但是当我使用该搜索功能时,在{ {1}},它表示“ Npgsql.PostgresException:'42883:运算符不存在:integer = text'”。
'selectQuery'看起来像这样:
da.Fill(ds)
和idList看起来像这样:
SELECT id, category, source_company, old_value, old_desc, new_value, new_desc, reference1, reference2 FROM masterfiles.xref WHERE company_name = @company AND id IN (@idList) ORDER BY category, old_value, source_company
我将异常解释为ID必须是整数,但是我无法弄清楚如何将ID列表作为整数传递给1475,1476,1477,1331,1332
方法-即使那是问题在这里。我是否需要将ID列表构建为数组并将列表以这种方式传递给GetDgvData()
?还是在GetDgvData()
中将每个ID都转换为整数?