簡體   English   中英

SqlConnection.Open()返回一個StackOverflow異常

[英]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什么問題?
  • 99.9%的時間,您可以在數據庫中執行JOIN來獲得更好的性能。
  • 不要嘗試推出自己的“ ORM”。 如果您不希望EF或NHibernate膨脹,請使用Dapper之類的工具 或者,堅持使用ADO( DataTableDataAdapter等)
using (SqlConnection SqlCon = new SqlConnection(ConnectionString)) {

您的連接字符串變量是否真的命名為ConnectionString? 您是否可能與類型名稱沖突? 由於未在顯示的代碼中聲明它,因此我假設它是一個類變量,因此您應該遵守常規的命名約定,即_connectionString 您的連接字符串是什么樣的?

好的,我知道了。 這是因為整個演示應用程序的體系結構不正確。 一些對象具有一個或多個其他對象作為屬性,並且由於體系結構中的某些愚蠢錯誤而導致; 遞歸調用了作為從數據庫中獲取數據的基礎的“獲取”操作,從而導致StackOverflow異常,該異常實際上是初始化的大量數據庫連接,最終將堆大小增大到導致該異常的程度。

我嘗試總結以上段落中的所有內容,因為考慮到大量代碼,發布完整的源代碼是無用的。

謝謝大家的幫助,尤其是@Guffa在主帖子上的評論,這迫使我從頭開始研究整個問題,而不是堅持使用異常堆棧。

暫無
暫無

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

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