2017-09-25 189 views
0

问题领域是我有一个db文件与〜90000行和6列。我得到了一个Select查询,我得到了所有必需的行和列,并且工作正常。现在是我用这些记录填充DataTable的东西。我用SQliteDataAdapter Fill Method做了这个,大约需要1,3秒,在这之后我用这些数据填充我的ObservableCollection(< - 绑定到DataGrid),这也需要约1,3秒。因此,这里是我的代码C#SQLiteDataAdapter填充方法很慢

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秒的用户体验不太好..

编辑 所以这才是我的DB设计: enter image description here

这是Tbl_Material和Tbl_Technik之间的多对多关系 而我的Select查询给了我所有来自Tbl_Material的entrys(〜90k)以及另外那些来自Tbl_Besitzt的列,我可以在其中找到技术ID 以便我可以过滤(用于一个复选框)哪些entrys属于我的MaterialID 在我的数据库文件MaterialId从Tbl_Materiallis TE是一个PK,也从Tbl_Technik TechnikID - 不是你在设计图像纳闷,我没有得到他们到模型..

非常感谢!

+0

是的这就是正确的,但如果我这样做不化背景线程它并没有改变......我会编辑我的代码,使螺纹心不是必要的......任何其他帮助的想法? – user8574993

回答

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虚拟化。这是一个相当大的话题,但网络上有很多信息。

+0

我按照你所描述的方式改变了它,现在它就像〜250ms填充列表!非常感谢!我将编辑我的文章,以便您可以看到我的数据库设计,所以也许你可以看看? – user8574993