2017-09-25 232 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