C# Open()返回StackOverflow异常
我试图找到解决这个问题的办法,但没有。问题是: 我正在加载一组用户的数据,并为每个用户创建一个对象。每个用户对象都有许多对象属性。结构如下:C# Open()返回StackOverflow异常,c#,sql,sql-server,sqlconnection,C#,Sql,Sql Server,Sqlconnection,我试图找到解决这个问题的办法,但没有。问题是: 我正在加载一组用户的数据,并为每个用户创建一个对象。每个用户对象都有许多对象属性。结构如下: public class User { public int ID { get; set; } public string Name { get; set; } public City City { get; set; } public Office Office { get; set; } } 城市级别: public clas
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异常(请参阅我下面编写的“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);
}
如何解决此错误?或者我应该用更好的方法来做这件事 评论有点太长了
- 您真的需要从数据库加载所有数据吗?最好只获取所需的列和行
- 为什么要将
复制到数据表
?仅使用词典
有什么问题数据表
- 99.9%的情况下,在数据库中执行
s时,您将获得更好的性能JOIN
- 不要试图推出自己的“ORM”。如果你不想要EF或NHibernate的膨胀,请使用类似的方法。或者,坚持使用ADO(
,DataTable
等)DataAdapter
您的连接字符串变量真的命名为ConnectionString吗?您是否可能与类型名称冲突?由于它没有在显示的代码中声明,我假设它是一个类变量,因此您应该遵守传统的命名约定,即
\u connectionString
。你的连接字符串是什么样子的?好了,伙计们,我知道了。这都是因为整个演示应用程序的体系结构存在缺陷。一些对象具有一个或多个其他对象作为属性,这是由于架构中存在一些愚蠢的错误;“fetch”操作作为从数据库获取数据的基础,被递归调用,导致StackOverflow异常,这实际上是大量数据库连接被初始化,最终使堆大小增加到导致异常的程度
我试图总结上面所写的段落中的所有内容,因为考虑到大量的代码,发布完整的源代码是无用的
感谢所有帮助过我的人,特别是@Guffa在主帖子上的评论,这迫使我从头开始调查整个问题,而不是坚持异常堆栈 HandleException是否有可能调用自己?可以显示堆栈跟踪吗?当然,在使用行和引用表之前,将temp变量设置为null似乎不是一个好主意。设置后,至少移动temp=nulldict@Steve:在设置
dict
之前或之后,将temp
变量设置为null
,没有任何区别。获取数据行后,代码中不再使用对数据表的引用。将引用设置为null是毫无意义的。那么堆栈上有什么?通常堆栈溢出是由无限递归引起的。我在您所展示的内容中没有发现任何递归代码,因此问题可能出在代码之外。引发堆栈溢出的代码只是代码中堆栈最终增长过多的地方,实际问题是导致堆栈首先增长的代码。这听起来是合理的。这听起来也与堆栈溢出错误IMO.1无关。我有两种账户类型。第一个是“用户”,即正式员工,第二个是“客户”。不会有超过50-75个“用户”,显示的数据包含添加/修改/更新该数据的用户的详细信息。这就是为什么我没有在几分钟内访问数百次数据库,而是将用户详细信息加载到本地内存中。2.Fetch函数有不同的版本。只有当需要一行数据并最终将其转换为字典时,才使用此方法。我知道也可以使用DataTables,但是一行一个表,不,谢谢,我们将对此进行研究。(4) 再次感谢你,我也会看看那个。这个代码是公正的;你可以说,一个原型。我正在尝试不同的方法,并将坚持使用最好的方法。“fetch”函数实际上是类的一部分,连接字符串是通过构造函数初始化的。ConnectionString是数据库对象的属性。
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;
}
SqlCon.Open();
using (SqlConnection SqlCon = new SqlConnection(ConnectionString)) {