问题域是我有一个包含~90000行和6列的db文件。我有一个Select查询,在那里我获得了我所需的所有行和列,并且工作正常。现在是我用这些记录填充DataTable的东西。我使用SQliteDataAdapter Fill Method执行此操作,这需要大约1,3秒,然后我用这些数据填充我的ObservableCollection(< - Bound to DataGrid),这也需要约1,3秒。所以这是我的代码
private void GetSelectedMaterial()
{
DataTable dtMaterial = new DataTable();
materialColl.Clear(); // Clearing ObservableCollection
Trace.WriteLine("GetSelectedMaterial TS " + DateTime.Now + DateTime.Now.Millisecond);
using (SQLiteConnection connection = new SQLiteConnection(dbConnection))
using (SQLiteCommand cmd = connection.CreateCommand())
{
connection.Open();
query = "SELECT * FROM Tbl_Materialliste LEFT JOIN(SELECT * FROM Tbl_Besitzt k WHERE k.TechnikID = '" + teTechnikID + "') as k ON k.MaterialID = Tbl_Materialliste.MaterialID";
dataAdapter = new SQLiteDataAdapter(query, connection);
Trace.WriteLine("query: " + DateTime.Now + DateTime.Now.Millisecond);
dtMaterial.Columns.Add("Checked", typeof(bool));
Trace.WriteLine("here comes the fill: " + DateTime.Now + DateTime.Now.Millisecond);
dataAdapter.Fill(dtMaterial);
Trace.WriteLine("Checkbox: " + DateTime.Now + DateTime.Now.Millisecond);
DetermineCheckBox(dtMaterial, teTechnikID, 8);
Trace.WriteLine("SQL TS: " + DateTime.Now + DateTime.Now.Millisecond);
}
FillMaterialColl(dtMaterial);
}
private void FillMaterialColl(DataTable dtMaterial)
{
foreach (DataRow dr in dtMaterial.Rows)
{
Material mat = new Material();
mat.isChecked = (bool)dr.ItemArray[0];
mat.materialID = (string)dr.ItemArray[1];
mat.materialkurztext = (string)dr.ItemArray[2];
mat.herstellername = (string)dr.ItemArray[3];
mat.herArtikenummer = (string)dr.ItemArray[4];
mat.dokument = (string)dr.ItemArray[5];
mat.substMaterial = (string)dr.ItemArray[6];
materialColl.Add(mat);
}
}
我知道ObservableCollections正在消耗性能但是有一些方法可以用另一种方式来做到这一点吗?有人说使用DataReader而不是DataAdapter,但DataAdapter应该使用DataReader,所以我认为性能没有任何改进。所以主要的问题是,如果显示新材料大约需要3-4秒,那么这个过程需要很长时间并且用户体验不是很好..
这是Tbl_Material和Tbl_Technik之间的多对多关系 我的Select查询给了我来自Tbl_Material(~90k)的所有托管以及来自Tbl_Besitzt的那些我可以找到technikID的列 这样我就可以过滤(对于一个复选框),它属于我的MaterialID 在我的DB文件中,来自Tbl_Materialliste的MaterialId是一个PK,也是来自Tbl_Technik的TechnikID - 不是你想知道设计图像,我没有让他们进入模型..
非常感谢!
答案 0 :(得分:0)
如果不了解数据库的架构和设计,就很难调查数据库的性能问题。在SQL查询中,有一个join
表达式。您需要确保索引相应的数据字段,以便快速进行连接操作。这还取决于两个表的数据大小。
为了加快搜索结果的显示速度,您应该避免在ObservableCollection<T>
中逐项添加它们。这是因为每次添加新项目时,绑定引擎都会将此项目传输到DataGrid
,从而导致网格执行显示记录所需的所有操作。
如果您真的不需要集合是可观察的(例如,您不会在视图中添加或删除任何项目),那么只需将其设为IEnumerable<T>
:
public IEnumerable<Material> Materials
{
get { return this.materials; }
private set
{
// Using the PRISM-like implementation of INotifyPropertyChanged here
// Change this to yours
this.SetProperty(ref this.materials, value);
}
}
在你的方法中,创建一个本地List<Material>
,填充它,然后公开到视图:
List<Material> materials = new List<Material>();
// fill the list here
// ...
// finally, assign the result to your property causing the binding to do the job once
this.Materials = materials;
如果你需要ObservableCollection<T>
,你可以做同样的伎俩 - 创建一个本地副本,填充它,最后公开。
如果这没有帮助,您应该尝试使用UI虚拟化。这是一个相当大的话题,但网上有很多信息。