使用SqlDataReader填充c#中的List <T>

我有一个类如下,

class Student
{
    public string Name {get; set;}
    public string Surname {get; set;}
    public int Age {get; set;}
    public string Address {get; set;}
}

我有一个包含50,000条记录的MySql表。表的结构如下,

ID        NAME       SURNAME        AGE          ADDRESS
1         Joe        Philip         20           Moscow
2         Misha      Johny          25           London
...

我有一个C#代码,

List students = new List();
string sql = "SELECT name,surname,age,address FROM Students";
command.CommandText = sql;
MySqlDataReader reader = command.ExecuteReader();
while(reader.Read())
{
    Student st = new Student();
    st.Name = reader["Name"].ToString();
    st.Surname = reader["Surname"].ToString();
    st.Age = Convert.ToInt32(reader["Age"].ToString());
    st.Address = reader["Address"].ToString();
    students.Add(st);
}

但它的工作非常缓慢。您建议使用哪种方法使此代码运行得更快?

更新:

当我使用此代码时,

DataTable dt = new DataTable();
adapter.Fill(dt);

它运作良好,速度非常正常。但是我用自己的课程尝试的问题是什么?

1
如果我使用数据集,则所有这些数据都将位于memmory中。如果我想使用自己的课程,那么差异是什么?
额外 作者 namco,
看我的回答;如果你告诉我们你将如何处理这个学生数据,你可能会得到更好的答案。
额外 作者 Jacob,
我们更重要的一点是,您不需要从数据库中加载所有记录。如果您只需要数据的子集,则可以使用 where 子句限制查询。
额外 作者 Jacob,
出于好奇,为什么需要将整个数据库表读入内存 ?这是数据库的一般概念,它们可以保存比存储器更多的数据,并且我们应该按记录处理数据记录。
额外 作者 Vlad,
这是它可能会得到的速度,这里没有明显的增强或疏忽 - 你需要在内存中所有这些记录吗?
额外 作者 BrokenGlass,
该代码无法编译。您正在为 int 属性(年龄)分配 string
额外 作者 Klaus Byskov Pedersen,
当然很慢。不要一次性将50k记录读入内存!
额外 作者 Gabe Moothart,

2 答案

如果代码运行缓慢,最大的原因是有50,000条记录。您需要具有50,000 Student 对象到底是什么?如果您可以找到解决问题的方法而无需阅读所有这些记录并创建所有这些对象,那么您将拥有更快的代码。

更新</强>

使用你自己的课很好。这是因为你的代码是 I/O绑定(你花了大部分时间等待I/O)。为了避免所有I/O,您可以减少检索的数据量(可能通过消除数据中不相关的列或行)或通过更复杂的查询或存储过程对数据库进行处理。

更新2

要回答你的后续问题(为什么创建对象列表比获取 DataSet 慢),我希望将整个查询作为 DataSet 读取只会是比对象创建稍快。我不熟悉MySQL .NET库的实现方式。令我惊讶的是,这两种方法在速度上会有的差异。也许 MySqlDataReader 就像使用内部 DataSet 一样愚蠢。如果两者之间的性能差异很大,那么该库的作者可能应该修复它。

更新3

MySqlDataAdapter或MySqlDataReader进行批量转移?的答案有一个好小费;设置阅读器的 BatchSize 可能会有所帮助。如果批量大小对于读者而言太小,那么使用像您这样的大量记录会降低其效率。

5
额外
我写考试检查程序。我将使用这个和另一个我没有在这里显示的数据来确定学生的分数。我可以在这里使用DataSet而不是Student类。但我更喜欢使用自己的课程。 RAM没有任何问题。仅在使用数据填充List时出现问题。它工作得很慢。
额外 作者 namco,
在不知道您对数据进行何种处理的具体情况下,我们无法提供更多帮助。更快的代码是更少的代码,因此尝试找到一种方法来减少代码(例如,将一些处理卸载到数据库)。查看我的更新。
额外 作者 Jacob,
额外 作者 Jacob,

使用记录索引而不是coulmname使性能更好一些 使用

st.Name = reader[0].ToString();
instead of
st.Name = reader["Name"].ToString();

and 
st.Name = reader[0].ToString();
instead of 
st.Name = reader["surname"].ToString();
1
额外
另请注意,字符串索引需要具有适当的区分大小写,否则会非常慢。在这种情况下,MySQL ADO.NET实现很奇怪。它仅用于MySQL ADO,我测试的每个其他连接器都运行良好。
额外 作者 nawfal,