C# 循环SQL查询的正确方法?

C# 循环SQL查询的正确方法?,c#,mysql,sql-server,C#,Mysql,Sql Server,我有一个列表,通过传递学生班级列表来检索学生的成绩 然后,它通过数据库查询学生的名字来获取学生的成绩。这段代码运行得很好,但是,当studentList的大小增加时,这段代码执行起来非常慢 通过sql查询循环列表的正确方法是什么 private List<StudentClass> getStudentGrades(List<StudentClass> studentList) { for (int i =0; i < studentList.Count;

我有一个列表,通过传递学生班级列表来检索学生的成绩

然后,它通过数据库查询学生的名字来获取学生的成绩。这段代码运行得很好,但是,当studentList的大小增加时,这段代码执行起来非常慢

通过sql查询循环列表的正确方法是什么

private List<StudentClass> getStudentGrades(List<StudentClass> studentList)
{
    for (int i =0; i < studentList.Count; i++)
    {
        string sqlcommand = "SELECT StudentGrades FROM Students WHERE StudentName=@StudentName";
        conn.Open();
        using (SqlCommand cmd = new SqlCommand(sqlcommand, conn))
        {
            cmd.Parameters.AddWithValue("@StudentName", studentList[i].StudentName);
            cmd.ExecuteNonQuery();
            SqlDataReader reader = cmd.ExecuteReader();

            while (reader.Reader())
            {
                studentList[i].StudentGrades = int.Parse(reader["StudentGrades"].ToString());
            }
        }
    }

    return studentList;
}

public class StudentClass
{
    public string StudentName {get; set; }
    public int StudentGrades {get; set; }
}
private List getStudentGrades(List studentList)
{
for(int i=0;i
首先-不必执行两次命令。您首先调用的是
ExecuteNonQuery
(它将无效,因为
ExecuteNonQuery
不返回数据,但它会减慢执行速度,因为请求实际上被传递到SQL server并正在执行)。然后,您将调用
ExecuteReader
,实际从中检索数据

第二个问题-您正在为每个学生执行新查询。所以,若列表中有1000名学生,将执行1000个查询

考虑首先从数据库中获取所有数据,然后相应地更新您的
学生列表


类似于获取
首先选择StudentName,StudentGrades FROM Students
,将结果保存到某个字典(或任何您想要的地方),然后在
studentList
上进行循环,首先-您无需执行两次命令。您首先调用的是
ExecuteNonQuery
(它将无效,因为
ExecuteNonQuery
不返回数据,但它会减慢执行速度,因为请求实际上被传递到SQL server并正在执行)。然后,您将调用
ExecuteReader
,实际从中检索数据

private List<StudentClass> getStudentGrades(List<StudentClass> studentList)
{
    string sqlcommand = "SELECT StudentGrades FROM Students WHERE StudentName=@StudentName";
    var conn = new SqlConnection();
    SqlCommand cmd = new SqlCommand(sqlcommand, conn);
    cmd.Parameters.Add("@StudentName");
    using (conn)
    {
        conn.Open();
        for (int i = 0; i < studentList.Count; i++)
        {
            cmd.Parameters[0].Value= studentList[i].StudentName;
            studentList[i].StudentGrades = (int)cmd.ExecuteScalar();
        }            
    }

    return studentList;
}
第二个问题-您正在为每个学生执行新查询。所以,若列表中有1000名学生,将执行1000个查询

考虑首先从数据库中获取所有数据,然后相应地更新您的
学生列表

类似于获取
首先选择StudentName,StudentGrades FROM Students
,将结果保存到某个字典(或任何您想要的地方),然后循环查看
studentList

私有列表获取StudentGrades(列出studentList)
private List<StudentClass> getStudentGrades(List<StudentClass> studentList)
{
    string sqlcommand = "SELECT StudentGrades FROM Students WHERE StudentName=@StudentName";
    var conn = new SqlConnection();
    SqlCommand cmd = new SqlCommand(sqlcommand, conn);
    cmd.Parameters.Add("@StudentName");
    using (conn)
    {
        conn.Open();
        for (int i = 0; i < studentList.Count; i++)
        {
            cmd.Parameters[0].Value= studentList[i].StudentName;
            studentList[i].StudentGrades = (int)cmd.ExecuteScalar();
        }            
    }

    return studentList;
}
{ string sqlcommand=“从StudentName=@StudentName的学生中选择StudentGrades”; var conn=new SqlConnection(); SqlCommand cmd=新的SqlCommand(SqlCommand,conn); cmd.Parameters.Add(“@StudentName”); 使用(康涅狄格州) { conn.Open(); for(int i=0;i
注意:您应该在一个查询中检索整个列表,这样会更好。

私有列表getStudentGrades(list studentList)
{
string sqlcommand=“从StudentName=@StudentName的学生中选择StudentGrades”;
var conn=new SqlConnection();
SqlCommand cmd=新的SqlCommand(SqlCommand,conn);
cmd.Parameters.Add(“@StudentName”);
使用(康涅狄格州)
{
conn.Open();
for(int i=0;i

注意:您应该在一个查询中检索整个列表,这样会更好。

正如其他用户所指出的,您不需要ExecuteOnQuery

但更大的问题是,SQL语句一次只返回一个学生的数据。是否有其他字段可用于同时选择组中的所有学生?也就是说,是否有“类”字段或类似的内容,因此您可以执行以下操作:

select studentgrades
  from students
 where class = @class
如果没有,您仍然可以使用in子句编写一种难看的sql语句。因此:

select studentgrades
  from studens
 where studentname in ('studentname1', 'studentname2', etc. )
使用这种方法,您可以将代码修改为以下内容:

private List<StudentClass> getStudentGrades(List<StudentClass> studentList)
{
        string studentListParam = "";
        foreach(StudentClass student in studentlist)
        {
           // blah blah stuff to only add comma if not first element
           studentListParam = studentListParam + ", '" + student.StudentName + "';
        }

        string sqlcommand = @"
SELECT StudentName, StudentGrades
  FROM Students
 WHERE StudentName in (" + studentlist + ")";
        conn.Open();
        using (SqlCommand cmd = new SqlCommand(sqlcommand, conn))
        {
            cmd.Parameters.AddWithValue("@StudentName", studentList[i].StudentName);
            cmd.ExecuteNonQuery();
            SqlDataReader reader = cmd.ExecuteReader();

            while (reader.Reader())
            {
                StudentClass student = studentList.Where(s => s.StudentName == string.Parse(reader["StudentName"]);
                student.StudentGrades = int.Parse(reader["StudentGrades"].ToString());
            }
        }
    }

    return studentList;
}

public class StudentClass
{
    public string StudentName {get; set; }
    public int StudentGrades {get; set; }
}
private List getStudentGrades(List studentList)
{
字符串studentListParam=“”;
foreach(学生名单中的学生班级学生)
{
//如果不是第一个元素,就只添加逗号
studentListParam=studentListParam+”,“+student.StudentName+”;
}
字符串sqlcommand=@”
选择StudentName,StudentGrades
来自学生
其中StudentName位于(“+studentlist+”)中;
conn.Open();
使用(SqlCommand cmd=newsqlcommand(SqlCommand,conn))
{
cmd.Parameters.AddWithValue(“@StudentName”,studentList[i].StudentName”);
cmd.ExecuteNonQuery();
SqlDataReader=cmd.ExecuteReader();
while(reader.reader())
{
StudentClass student=studentList.Where(s=>s.StudentName==string.Parse(reader[“StudentName]”);
student.StudentGrades=int.Parse(reader[“StudentGrades”].ToString());
}
}
}
返回学生名单;
}
公共课学生课
{
公共字符串StudentName{get;set;}
public int StudentGrades{get;set;}
}
很明显,您需要一些空检查和各种其他位的错误检查来实现ma