[英]SqlConnection.Open() returns a StackOverflow Exception
我試圖為此找到解決方案,但沒有。 這是問題所在:
我正在加載一堆用戶的數據並為每個用戶創建一個對象。 每個用戶對象都有許多對象屬性。 結構如下:
public class User {
public int ID { get; set; }
public string Name { get; set; }
public City City { get; set; }
public Office Office { get; set; }
}
市級:
public class City {
public int ID { get; set; }
public string Name { get; set; }
public string Keyword { get; set; }
}
辦公類:
public class Office {
public int ID { get; set; }
public string Address { get; set; }
public int CityID { get; set; }
}
用戶對象具有許多其他類似的屬性,例如City&Office,它們基本上是類對象。
現在是主要問題。 每當我嘗試將所有用戶加載到詞典的集合中時,SqlCon.Open()都會發生StackOverflow異常(請參閱下面編寫的“獲取”函數)。 這是我加載所有內容的方式:
//Code to load users
Dictionary<int, User> Users = new Dictionary<int, Users>();
DataTable usersData = new DataTable();
//The Fetch function has two version. The first one; which is mentioned in this post, returns the result as Dictionary<string, object>().
//The second version of the function returns the result in the form of the a DataTable and is only used when multiple rows are required from the database. The following returns a set of rows in a DataTable.
Globals.MainDatabase.Fetch("SELECT * FROM users", out usersData);
foreach (DataRow row in usersData.Rows) {
User user = new User();
user.ID = Convert.ToInt32(row["id"]);
user.Name = row["name"].ToString();
user.City = Cities.Get(Convert.ToInt32(row["city_id"]));
user.Office = Offices.Get(Convert.ToInt32(row["office_id"]));
Users.Add(user.ID, user);
}
方法“ Cities.Get(Int32 id)”和“ Offices.Get(Int32 id)”使用以下函數從數據庫中獲取數據。
public void Fetch(string query, out Dictionary<string, object> results) {
var dict = new Dictionary<string, object>();
try {
using (SqlConnection SqlCon = new SqlConnection(ConnectionString)) {
using (SqlCmd = new SqlCommand()) {
SqlCmd.Connection = SqlCon;
SqlCmd.CommandType = CommandType.Text;
SqlCmd.CommandText = query;
SqlCon.Open();
DataTable temp = new DataTable();
using (SqlDataAdapter SqlAdp = new SqlDataAdapter(SqlCmd)) {
SqlAdp.SelectCommand = SqlCmd;
SqlAdp.Fill(temp);
}
DataRow row = temp.Rows[0];
temp = null;
dict = row.Table.Columns
.Cast<DataColumn>()
.ToDictionary(col => col.ColumnName, col => row.Field<object>(col.ColumnName));
}
}
}
catch (Exception ex) {
HandleException(ex, "An error occurred when tried to fetch data.", query);
}
results = dict;
dict = null;
}
我意識到創建用戶對象時會多次調用此“獲取”功能。 “ StackOverflow”異常恰好發生在此行:
SqlCon.Open();
我該如何解決這個錯誤? 還是我應該使用更好的方法來做到這一點?
評論太久了
ALL
數據嗎? 最好只是抓住您需要的列和行。 DataTables
復制到Dictionaries
? 僅使用DataTable
什么問題? JOIN
來獲得更好的性能。 DataTable
, DataAdapter
等) using (SqlConnection SqlCon = new SqlConnection(ConnectionString)) {
您的連接字符串變量是否真的命名為ConnectionString? 您是否可能與類型名稱沖突? 由於未在顯示的代碼中聲明它,因此我假設它是一個類變量,因此您應該遵守常規的命名約定,即_connectionString
。 您的連接字符串是什么樣的?
好的,我知道了。 這是因為整個演示應用程序的體系結構不正確。 一些對象具有一個或多個其他對象作為屬性,並且由於體系結構中的某些愚蠢錯誤而導致; 遞歸調用了作為從數據庫中獲取數據的基礎的“獲取”操作,從而導致StackOverflow異常,該異常實際上是初始化的大量數據庫連接,最終將堆大小增大到導致該異常的程度。
我嘗試總結以上段落中的所有內容,因為考慮到大量代碼,發布完整的源代碼是無用的。
謝謝大家的幫助,尤其是@Guffa在主帖子上的評論,這迫使我從頭開始研究整個問題,而不是堅持使用異常堆棧。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.