2013-03-13 40 views
4

我正在開發一個在非常大的表中搜索信息的方法。由於我沒有使用ORDER BY或查詢中的任何特殊內容(只是簡單的SELECT id,description FROM complain WHERE description like 'YOUR TEXT HERE'"),我希望通過返回批次結果來提供更加動態的用戶體驗。這與在Management Studio中運行查詢類似。方法「部分」返回

一些細節,我的調用堆棧並不大,但並不是所有的方法都是相同的。每個不同層(Interface,SearchBLL和SearchDAL)分別有buttonSearchClick,performCleanSearchsearchComplainBasedOnDetailInfo

我想過如何創建一個像List<Complain>那樣的異步方法,但看起來並不乾淨。我將不得不做3層異步。有沒有人有更好的想法如何實現這個?或者這是做到這一點的最佳方式?

EDIT1:我已經成功地使用SqlCommand.BeginExecuteReader一起異步處理在連接字符串來從查詢的結果,因爲它們出現...現在我必須找出一種方法,使我的DAL方法是異步的,所以上層可以獲取結果也異步...我想實現某種緩衝區...也許是一個隊列...

編輯2:我不是在找一個分頁解決方案或像一個twitter(你在哪裏滾動和搜索新結果),因爲我知道一個事實,即用戶將不得不讀取所有提取的信息...

+1

這可能是你有幫助http://stackoverflow.com/questions/9234730/respond-to-async-sql-calls -as-they-complete – 2013-03-13 14:12:04

+0

您可以使用'yield return'來評估您的結果。 – Romoku 2013-03-13 14:15:10

+0

類似於@Luke所說的 - 你可能會考慮分頁:http://shackoverflow.com/questions/5335797/microsoft-sql-server-paging – 2013-03-13 14:17:15

回答

1

你可以使用一個BackgroundWorker並在DoWork讓你批次做這樣的事情:

DataTable dt; 
int iRecords = 0; 
do 
{ 
    dt = new DataTable(); 
    using(SqlConnection con = new SqlConnection("")) 
    { 
    SqlCommand cmd = new SqlCommand(string.Format("SELECT TOP 100 * FROM complain where ID > {0}", iRecords)); 
    SqlDataAdapter sda = new SqlDataAdapter(cmd); 
    sda.Fill(dt); 
    //Report your progress here 
    } 
} while(dt.Rows.Count != 0) 
+0

不「填充」只有當查詢完成時返回?!?我的意思是填充似乎並不是異步... – Leonardo 2013-03-13 14:29:11

+0

@Leonardo它不需要是'async'正在執行並在工作線程上返回bitesize塊。如果您想要更多地控制數據庫查詢的執行,請考慮實體框架並將其與「TaskLibrary」相結合。 – LukeHennerley 2013-03-13 14:31:21

0

你可以從你的方法返回一個IEnumerable<Task<IEnumerable<T>>>(T將被設置爲任何類型的項目)。每個Task<IEnumerable<T>>將代表將來可能收到的一批信息。該方法本身可以是一個迭代器塊,在獲取每個批處理時會產生每個批處理,或者根據您的查詢方法,您可以批量整個序列而無需編寫迭代器塊。

然後從來電者的角度來看,他們可以寫這樣的事:

foreach(Task<IEnumerable<T> batch in GetBatches()) 
{ 
    updateUIWithBatch(await batch); 
} 
+0

你能提供一個更廣泛的代碼示例或者可以指出哪裏可以找到更「端到端」的示例嗎? – Leonardo 2013-03-13 16:55:33

+0

@Leonardo真的,不知道你是如何查詢各個批次的。 – Servy 2013-03-13 16:56:22