2013-10-03 88 views
1

首先,我在2012年VB搜索文本框與數據庫中所有的

工作,我有我的搜索數據庫的問題。它太慢了,實際上填充ListView是困擾我的東西。
我有TextChange事件文本框。它的即時搜索。因此,當我開始在該文本框中編寫代碼時,它開始過濾數據庫並填充ListView中的數據。

這是text box代碼和Load程序

Private Sub txtID_TextChanged(sender As Object, e As EventArgs) Handles txtID.TextChanged 
    Load("SELECT * FROM table WHERE id LIKE '" & txtID.Text & "%'") 
End Sub 


Private Sub Load(ByVal strQ As String) 
    List.Items.Clear() 
    cmd = New SqlClient.SqlCommand(strQ, con) 
    dr = cmd.ExecuteReader() 
    If dr.HasRows = True Then 
     While dr.Read 
      Dim X As ListViewItem 
      X = List.Items.Add(dr(0)) 
      X.SubItems.Add(dr(2)) 
      X.SubItems.Add(dr(3)) 
      X.SubItems.Add(dr(4)) 
      X.SubItems.Add(dr(1)) 
      X.SubItems.Add(dr(5))    
     End While 
    End If 
End Sub 

所以,每次我打一個字母時它調用加載程序。

而且我有這麼多的數據和它去這麼慢。你能以某種方式幫助我嗎?有沒有解決方法?

+3

每當有人按下某個鍵時,您正在對數據庫執行搜索?並想知道爲什麼它很慢? –

+0

不要吼我。這就是爲什麼我要求一個想法:( – GigaC

+3

@GigaC相信我,他沒有對你大喊,你會知道,如果亞倫大叫。 – Taryn

回答

2

我不知道你怎麼過將可能加快這件事。連接和查詢數據庫的開銷很大,尤其是與按鍵或鍵入單詞的速度相比。在沒有嚴重影響正在輸入的用戶的情況下,沒有辦法做到這一點。

我的建議,而不是爲你等待用戶來告訴你,他們就完成了,你何必來進行搜索前打字。如果你想要做一些奇怪的自動完成的東西,那麼你將需要將數據緩存到比數據庫更接近應用程序的地方。

+0

這將是一個問題。我需要即時搜索(自動完成),而不是在用戶鍵入整個單詞並按回車後。你有這張照片嗎? :) 無論如何,在開始我加載所有的聯繫人並填寫ListView。我可以過濾ListView而不是數據庫嗎? – GigaC

+0

@GigaC與你在你的問題中所說的相沖突(稍後填寫ListView中的數據)。無論如何,這就是我所說的「緩存數據更接近應用程序」......如果您在過濾已填充的ListView時遇到問題,那麼也許您應該連貫地提出這個問題。 *聳聳肩* –

+0

我想說的是,在窗體的負載下,我必須從數據庫中填充ListView中的所有數據。但是我用同樣的方法進行搜索(一次又一次地從數據庫中獲取數據)。沒關係,只要告訴我可以使用LINQ方法過濾已填充的ListView。我剛讀了一下。 – GigaC

2

你需要創建一個類來保存搜索結果,像這樣:

Public Class SearchResult 
    Private _propID As String 
    Public Property ID() As String 
     Get 
      Return _propID 
     End Get 
     Set 
      _propID = Value 
     End Set 
    End Property 

Private _propName As String 
    Public Property PropName() As String 
     Get 
      Return _propName 
     End Get 
     Set 
      _propName = Value 
     End Set 
    End Property 
    ... 
End Class 

現在你查詢數據庫得到的所有結果以列表視圖中顯示,其存儲在List(Of SearchResult),像這樣的:

Private Function Load(ByVal strQ As String) As List(Of SearchResult) 
    Dim ListOfResults = New List(Of SearchResult) 
    cmd = New SqlClient.SqlCommand(strQ, con) 
    dr = cmd.ExecuteReader() 
    If dr.HasRows = True Then 
     While dr.Read 
      Dim X As New SearchResult() 
      X.PropID = dr(0) 
      X.PropName = dr(1) 
      ...    
     End While 
    End If 
End Sub 

您可以調用該代碼:

Dim AllSearchResults = Load("SELECT * FROM table WHERE id LIKE '" & txtID.Text & "%'") 

現在w ^母雞你想做的事,你可以將以下LINQ對緩存的一切(AllSearchResults)列表的搜索,例如:

Public Function DoSearch(searchText As String) As List(Of SearchResult)  
    Return From s In AllSearchResults Where s.PropID.Contains(searchText) Select c 
End Function 

最後,可以由用戶調用每個按鍵此LINQ過濾,像這樣的:

Private Sub txtID_TextChanged(sender As Object, e As EventArgs) Handles txtID.TextChanged 
    DoSearch(txtID.Text) 
End Sub 
+1

Dude ....真棒,如果這個作品,我會找到你並親吻你! 我會立即嘗試代碼! – GigaC

+1

向'DoSearch'函數添加了返回類型'As List(Of SearchResult)'。 –

0

一個接一個相當程度的削減開銷下來的方式來等待發出查詢,直到輸入的文本的長度爲3(或更好,但5)字符。這是非常,非常不可能所有的客戶(或任何這些都是)以「S」將是有意義或有幫助的任何人,除非在極少數情況下找一個人「審計局......」。在第一個查詢完成並顯示之前,人們必須在第二個和第三個字符中輸入!

要儘量做到一個非常糟糕的想法不那麼糟糕,我會考慮的方式。一旦發出查詢(第一個字符,如果我真的,真的有),然後在後續的按鍵向下篩選這些結果。 (ala Aaron的「緩存數據更接近應用程序」)。

接下來的事情是Select *。我不知道桌子上有什麼,但是你真的需要每一列嗎?這似乎是某種選擇列表,您是否真的需要6個字段爲用戶提供進行選擇所需的信息?如果表中的列數超過6列,請立即將查詢範圍縮小至列表視圖中使用的6。一旦他們做出選擇,你就可以回頭,並通過ID或其他方式得到你需要的東西。

我個人使用更快的控制,但這是主觀的。

所有數據庫最終都會獲取休眠數據。客戶(或其他)是一次性購物者,永遠不會返回 - 他們是否需要列入清單?如果lastorderdate或lastupdateddate存在某個列,請構建查詢以選擇最近XX個月內處於活動狀態的查詢(如果不是,請參閱是否可以添加一個,因爲數據庫變大時問題不會變得更好!)。然後爲用戶提供一個複選框,根據需要擴大範圍,如「查看所有」等。如果用戶在80%的時間內加快速度,用戶不太可能不願意這樣做。

......那些只是我的頭頂。

相關問題