SqlConnection.Open() returns 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; }
}
城市class:
public class City {
public int ID { get; set; }
public string Name { get; set; }
public string Keyword { get; set; }
}
办公室class:
public class Office {
public int ID { get; set; }
public string Address { get; set; }
public int CityID { get; set; }
}
用户对象还有许多其他类似的属性,例如 City 和 Office,它们基本上都是 class 个对象。
现在是主要问题。每当我尝试将所有用户加载到字典集合中时,Whosebug 异常发生在 SqlCon.Open() 处(请参阅我在下面编写的 "Fetch" 函数)。以下是我加载所有内容的方式:
//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;
}
我意识到这个 "Fetch" 函数在创建用户对象时被多次调用。 "Whosebug" 异常恰好发生在这一行:
SqlCon.Open();
如何解决这个错误?或者我应该使用更好的方法来做到这一点?
评论有点长
- 您真的需要从数据库加载
ALL
数据吗?最好只抓取你需要的列和行。
- 为什么要将
DataTables
复制到 Dictionaries
?只使用 DataTable
有什么问题?
- 99.9% 的时间您将在数据库中执行
JOIN
秒时获得更好的性能。
- 不要尝试自己动手 'ORM'。如果您不想要 EF 或 NHibernate 的膨胀,请使用 Dapper 之类的东西。或者,坚持使用 ADO(
DataTable
、DataAdapter
等)
using (SqlConnection SqlCon = new SqlConnection(ConnectionString)) {
您的连接字符串变量真的名为 ConnectionString 吗?您是否有可能与类型发生名称冲突?由于它没有在显示的代码中声明,我假设它是一个 class 变量,所以你应该遵守传统的命名约定,即 _connectionString
。您的连接字符串是什么样的?
好的伙计们,我明白了。这都是因为整个演示应用程序的错误架构。某些对象具有一个或多个其他对象作为属性,并且由于体系结构中的一些愚蠢错误;作为从数据库中获取数据的基础的 "fetch" 操作被递归调用,导致 Whosebug 异常,这实际上是大量数据库连接被初始化,最终将堆大小增加到导致异常的程度。
我试图总结上面段落中的所有内容,因为考虑到大量代码,post获取完整的源代码是无用的。
感谢所有提供帮助的人,尤其是@Guffa 对主要 post 的评论,这迫使我从头开始调查整个问题,而不是坚持使用异常堆栈。
我试图为此找到解决方案,但没有成功。问题来了:
我正在加载一组用户的数据并为每个用户创建一个对象。每个用户对象都有许多对象属性。结构如下:
public class User {
public int ID { get; set; }
public string Name { get; set; }
public City City { get; set; }
public Office Office { get; set; }
}
城市class:
public class City {
public int ID { get; set; }
public string Name { get; set; }
public string Keyword { get; set; }
}
办公室class:
public class Office {
public int ID { get; set; }
public string Address { get; set; }
public int CityID { get; set; }
}
用户对象还有许多其他类似的属性,例如 City 和 Office,它们基本上都是 class 个对象。
现在是主要问题。每当我尝试将所有用户加载到字典集合中时,Whosebug 异常发生在 SqlCon.Open() 处(请参阅我在下面编写的 "Fetch" 函数)。以下是我加载所有内容的方式:
//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;
}
我意识到这个 "Fetch" 函数在创建用户对象时被多次调用。 "Whosebug" 异常恰好发生在这一行:
SqlCon.Open();
如何解决这个错误?或者我应该使用更好的方法来做到这一点?
评论有点长
- 您真的需要从数据库加载
ALL
数据吗?最好只抓取你需要的列和行。 - 为什么要将
DataTables
复制到Dictionaries
?只使用DataTable
有什么问题? - 99.9% 的时间您将在数据库中执行
JOIN
秒时获得更好的性能。 - 不要尝试自己动手 'ORM'。如果您不想要 EF 或 NHibernate 的膨胀,请使用 Dapper 之类的东西。或者,坚持使用 ADO(
DataTable
、DataAdapter
等)
using (SqlConnection SqlCon = new SqlConnection(ConnectionString)) {
您的连接字符串变量真的名为 ConnectionString 吗?您是否有可能与类型发生名称冲突?由于它没有在显示的代码中声明,我假设它是一个 class 变量,所以你应该遵守传统的命名约定,即 _connectionString
。您的连接字符串是什么样的?
好的伙计们,我明白了。这都是因为整个演示应用程序的错误架构。某些对象具有一个或多个其他对象作为属性,并且由于体系结构中的一些愚蠢错误;作为从数据库中获取数据的基础的 "fetch" 操作被递归调用,导致 Whosebug 异常,这实际上是大量数据库连接被初始化,最终将堆大小增加到导致异常的程度。
我试图总结上面段落中的所有内容,因为考虑到大量代码,post获取完整的源代码是无用的。
感谢所有提供帮助的人,尤其是@Guffa 对主要 post 的评论,这迫使我从头开始调查整个问题,而不是坚持使用异常堆栈。