簡體   English   中英

為返回多個表的存儲過程創建強類型數據集

[英]Create Strongly Typed Dataset for a stored procedure that return more than one table

我有一個執行3選擇的存儲過程。 如何創建可以訪問所有3個表並讀取數據的強類型數據集。 默認情況下,Visual Studio僅使用第1個表生成數據集

我已經嘗試使用visual studio Typed Dataset來拖放存儲過程。

存儲過程是這樣的:

Create Procedure GetData
As
Begin
Select ColA, ColB, ColC from TableA
Select ColD, ColE, ColF from TableB
Select ColG, ColH, ColI from TableC
End

如果你迫切希望這樣做,我認為你不會用純粹的強類型設計器生成的解決方案取得成功; tableadapters用於在db數據的本地數據表表示(強類型數據表)和返回行的數據庫查詢之間進行調解。 tableadapter中的“table”與數據表有關,而與數據庫表無關。

單個tableadapter不用作3個本地數據表和提供3個數據庫查詢輸出的遠程過程之間的中介。 主要是它無法做到這一點,因為沒有客戶端代碼可以用來識別你的sql ...

Select ColA, ColB, ColC from TableA
Select ColD, ColE, ColF from TableB
Select ColG, ColH, ColI from TableC

... select * from TableA的結果應該放在數據集等中的TableADataTable中。數據來自tableA的事實在通過線路的傳輸中丟失,因為它完全不相關,甚至可能不是真的。

當tableadapter正確地與單個select一起使用時,它會隱式地知道應該放入結果的數據表.TableADataTable具有相應的TableATableAdapter,TableATableAdapter從db中的某處選擇數據並將其存儲在TableADataTable中 - 沒有其他表在TableATableAdapter設計用於操作的數據集中,因此在運行查詢后不需要任何關於數據塊的位置的提示。 TableATableAdapter甚至可以加載一個查詢,該查詢根本不返回數據庫TableA中的任何數據; 只要它運行的查詢產生一組正確數字和類型的列,該數據就會進入TableADataTable,因為這就是TableATableAdapter硬編碼所做的事情。 它不提供其他數據表,也不關心任何其他數據表。

因為您的存儲過程無法向tableadapter指示應將哪個結果集存儲在哪個表中,所以您設想的解決方案無法工作。

簡單的規則是:“一只狗,一只完成” - “一個db查詢結果集,一個tableadapter,一個強類型數據表”

因此,我強烈建議您按照預期使用這些內容:

  • 為TableA,TableB和TableC創建3個tableadapter和相應的數據表
  • 在您的代碼中單獨填寫:

var ds = new StronglyTypedDataSet();
var ata as new TableATableAdapter();
ata.Fill(ds);
var bta as new TableBTableAdapter();
bta.Fill(ds);
var cta as new TableCTableAdapter();
cta.Fill(ds);

“我們希望避免單個頁面的多個數據庫調用”並不真正有意義 - 它聽起來像是一個你想象的問題的解決方案,而不是真正發生的問題。 通過嘗試在一次命中而不是3次中執行這些事情,可以獲得很少的性能優勢。您可能不同意,但測試它 - 不要只是預感。 匯總連接,緩存和准備語句,如果你真的認為它會有很大的幫助,可以同時執行3個語句。

如果你有9兆字節的數據需要從數據庫中取出,那么在每天結束時,每次3 mb的3次拉力與9次拉力的差異將是微不足道的。 你沒有等待30秒連接打開,一秒鍾讀取3 mb,等待另外30秒關閉它,廣告必須重新進行(總時間為183秒)並且所有瓶頸都歸因於連接管理。 即使您確實有一個超級延遲連接,需要30秒來傳輸SELECT而另外30秒才能開始讀取數據,您可以同時啟動3個請求,根據定義,它將花費相同的時間發送3個SELECT。調用1個過程調用(都需要61秒)


如果你不能同意嘗試一次性的原因是虛假的,那么你可能希望繼續嘗試通過你選擇的方法來做,在這種情況下,我認為你將不得不選擇:

使用標准數據適配器和數據集

然后將數據移動到鍵入的集合中以使用它

SqlConnection con = new SqlConnection("YourConnection String");
SqlDataAdapter da = new SqlDataAdapter();
DataSet ds = new DataSet();
SqlCommand cmd = new SqlCommand("storedprocedure", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@p1", whatever); //if you have parameters.
SqlDataAdapter da= new SqlDataAdapter(cmd);
da.Fill(ds);
con.Close();

現在你有一個包含3個表的數據集,你要弄清楚哪個表是哪個表。 我們假設ds.Tables [0]適用於TableA:

foreach(var ro in ds.Tables[0].Rows)
  typedDs.TableA.AddTableARow(ro.ItemArray);

對b和c表重復此操作

將3個查詢轉換為1

您的示例似乎表明您的所有3個表都具有相同的列數。 如果列也是相同的類型,那么您可以將查詢合並,並將它們加載到單個表適配器中,並將它們填充到單個強類型數據表中。 然后,您可能需要做更多工作才能將它們拆分為單獨的數據表。 也許修改查詢以返回列,以便您可以跟蹤數據的來源:

Select 'tableA' as wherefrom, ColA, ColB, ColC from TableA
UNION ALL
Select 'tableB' as wherefrom, ColD, ColE, ColF from TableB
UNION ALL
Select 'tableC' as wherefrom, ColG, ColH, ColI from TableC

這是一個爛攤子,一個麻煩,一個黑客


為什么這么難? 那么......引用另一句老話:如果它很難,你做錯了。 TableAdapters是以X方式設計的,你試圖以Y方式使用它們。 退后一步,檢查你為什么這么做的原因 - 這就是真正的問題所在

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM