簡體   English   中英

C#中的SQL嵌套查詢和連接打開問題

[英]SQL Nested Queries in C# and Connection Open Problem

我有三個表,我的要求是使用每個表的父記錄來獲取它們的記錄。

所以我有三個查詢。 這是一個代碼示例:

第一次查詢

SQLConnection con = new SQLConnection("connectionstring");

SQLCommand cmd1 = new SQLCommand (1stQuery,con);
SQLDataReader rs1 = cmd1.DataReader();

while (rs1.Read()) {

// Making 2nd Query, 2nd Query is using 1st Query result

SQLCommand cmd2 = new SQLCommand(2ndQuery,con);
SQLDataReader rs2 = cmd2.DataReader();

while (rs2.Read()){

//Making 3rd Query using 2nd Query result
}
}

它給出了一個錯誤,即已經有一個打開的DataReader。 我不想關閉SQL連接並為每個查詢打開它,因為這不利於性能。

我只想對所有查詢使用一個SQL連接。

您不需要關閉連接。 問題(錯誤提示)是您沒有在啟動下一個DataReader之前關閉它。

就像Oded所說的那樣,您遇到了“選擇N + 1”的問題,但是為了得到這個答案,讓我們忽略它。

最簡單的方法是在開始讀取下一個數據集之前,將整個第一個數據集讀取到內存中:

var list1 = new List<Foo>();
using (var rdr1 = cmd1.ExecuteReader())
{
    list1.Add(...);
}

var list2 = new List<Bar>();
var cmd2 = ...;
foreach (var item in list1)
{
    // assign parameters to cmd2 from item

    using (var rdr2 = cmd2.ExecuteReader())
    {
        list2.Add(...);
    }
}

... 等等。

另一個選項是在連接上啟用MARS ,這使您可以同時激活多個DataReader。 這幾乎總是一個壞主意,所以讓我們假裝我從未建議過。

如果要嵌套對數據庫的調用,則需要使用其他連接。

在這里,通過循環調用數據庫有一個更嚴重的問題-也稱為N + 1問題

我建議重寫數據庫和應用程序邏輯-在數據庫中使用聯接將單獨的查詢合並為一個並更改邏輯以使用結果。

我建議使用ExecuteDataSet 它將包含所有三個查詢的結果。 移動,這些查詢應在存儲過程中執行。

否則,您將邀請Sql注入

SQL注入

將您的連接字符串的MultipleActiveResultsets屬性設置為true,但是代碼的性能很差。 嘗試將查詢包裝在存儲過程中以避免循環。

暫無
暫無

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

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