所以我有一个显示db中所有项目的按钮和一个显示特定项目的按钮。
我的问题是,每次查询搜索是否都可能不执行,因为即使在第二个线程中完成也要花费时间。
我有第一个按钮
cmd.CommandText = "SELECT * FROM table";
using (var dr = cmd.ExecuteReader())
{
while (dr.Read())
{
this.cr.Add(new CrystalReport
{
item1 = dr["item1"].ToString(),
item2 = dr["item2"].ToString(),
item3 = string.IsNullOrEmpty(dr["item3"].ToString()) ? "" : dr["item3"].ToString(),
});
}
dr.Close();
}
dataGridView1.DataSource = cr.Select(r => new GridViewConstruct()
{ item1 = r.item1 , item2 = r.item2, item3 = r.item3}).ToList();
第二次
cmd.CommandText = "SELECT * FROM table";
using (var dr = cmd.ExecuteReader())
{
while (dr.Read())
{
this.cr.Add(new CrystalReport
{
item1 = dr["item1"].ToString(),
item2 = dr["item2"].ToString(),
item3 = string.IsNullOrEmpty(dr["item3"].ToString()) ? "" : dr["item3"].ToString(),
});
}
dr.Close();
}
dataGridView1.DataSource = cr.Select(r => new GridViewConstruct()
{ item1 = r.item1 , item2 = r.item2, item3 = r.item3 }).Where(x => x.something == something).ToList();
如果它与db不同,是否有可能获得它?
答案 0 :(得分:1)
我建议打开页面时仅加载一次数据。您可以将数据访问代码从按钮事件处理程序移至填充cr
ObservableCollection的共享方法。理想情况下,cr
应该包含GridViewConstruct
类型的项目,而不是CrystalReport
,例如:
cmd.CommandText = "SELECT * FROM table";
using (var dr = cmd.ExecuteReader())
{
while (dr.Read())
{
this.cr.Add(new GridViewConstruct
{
item1 = dr["item1"].ToString(),
item2 = dr["item2"].ToString(),
item3 = string.IsNullOrEmpty(dr["item3"].ToString()) ? "" : dr["item3"].ToString(),
});
}
dr.Close();
}
dataGridView1.DataSource = cr.ToList();
一旦加载了数据,就可以通过将cr
分配为数据源来初始化DataGridView。
您可以禁用按钮,直到数据加载完毕,然后更改按钮代码以使用存储在cr
ObservableCollection中的准备好的数据:
dataGridView1.DataSource = cr.ToList();
dataGridView1.DataSource = cr.Where(x => x.something == something).ToList();
这是一种可行的方法,因为无论如何您都需要所有记录;但是,如果需要过滤数据,那将是更改SELECT以包含WHERE条件和参数的最有效方法。
此方法的缺点是数据仅加载一次。但是,有几种刷新数据的方法。最简单的方法是在一个时间间隔后刷新数据,但是如果数据不经常更改,则会导致对服务器的许多冗余查询。因此,推送方法会更好。
如果使用SqlServer,则可以使用SqlDependency
,以便在数据更改时通知您的应用程序。请注意,该技术是为在侦听数据更改的客户端数量非常有限的Web或服务器应用程序中使用而开发的。