Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C SqlDataReader仅检索一行_C#_Sql Server - Fatal编程技术网

C# C SqlDataReader仅检索一行

C# C SqlDataReader仅检索一行,c#,sql-server,C#,Sql Server,我有一个问题,我列出了100多名学生,但reader只检索表中最后一名学生 string selectQuery = "SELECT * FROM Students WHERE firstName = @first AND lastName = @last"; using (SqlCommand sqlCommand = new SqlCommand(selectQuery, sqlConnection)) { sqlCommand.Parameters.Add("@first", S

我有一个问题,我列出了100多名学生,但reader只检索表中最后一名学生

string selectQuery = "SELECT * FROM Students WHERE firstName = @first AND lastName = @last";

using (SqlCommand sqlCommand = new SqlCommand(selectQuery, sqlConnection))
{
    sqlCommand.Parameters.Add("@first", SqlDbType.VarChar);
    sqlCommand.Parameters.Add("@last", SqlDbType.VarChar);

    foreach (Student student in studentList)
    {
        sqlCommand.Parameters["@first"].Value = student.first;
        sqlCommand.Parameters["@last"].Value = student.last;
    }

    using (SqlDataReader sqlReader = sqlCommand.ExecuteReader())
    {
        while (sqlReader.Read())
        {
            Console.WriteLine(sqlReader["firstName"].ToString());
            Console.WriteLine(sqlReader["lastName"].ToString());
        }
    }
}

出现问题的原因是您一次又一次地覆盖了单个2个参数。请参见代码中的注释:

string selectQuery = "SELECT * FROM Students WHERE firstName=@first and lastName=@last";
using (SqlCommand sqlCommand = new SqlCommand(selectQuery, sqlConnection))
{
    sqlCommand.Parameters.Add("@first", SqlDbType.VarChar);
    sqlCommand.Parameters.Add("@last", SqlDbType.VarChar);
    foreach (Student student in studentList) // addds 100 students
    {
        // overwrites the same parameter again and again.... so its only the last one
        sqlCommand.Parameters["@first"].Value = student.first;
        sqlCommand.Parameters["@last"].Value = student.last;
    }

    using (SqlDataReader sqlReader = sqlCommand.ExecuteReader()) 
    {// the query uses only 2 params so you need to change the query and the adding
        while (sqlReader.Read())
        {
            Console.WriteLine(sqlReader["firstName"].ToString());
            Console.WriteLine(sqlReader["lastName"].ToString());
        }
    }
 } 
解决方案使用complexer通过一个查询搜索所有这些问题,其中条件根据您的数据和数据所需的任意多个SqlParameters生成:

// create all the variable names
var firstVarName = Enumerable.Range(1, studentList.Count)
    .Select(i => $"@first_{i}")
    .ToList();
var lastVarName = Enumerable.Range(1, studentList.Count)
    .Select(i => $"@last_{i}")
    .ToList();

var cond = "firstName = {0} and lastName = {1}";

var whereOred = new StringBuilder("WHERE 1 = 0  -- false, just ease of formatting\n");

for (int i = 0; i < firstVarName.Count; i++)
{
    whereOred.AppendLine("   OR " + string.Format(cond, firstVarName[i], lastVarName[i]));
}

// adapt query to search all variable names
string selectQuery = $@"
SELECT *
FROM Students
{whereOred.ToString()}";

Console.WriteLine(selectQuery);
using (SqlCommand sqlCommand = new SqlCommand(selectQuery, sqlConnection))
{
    // add all the variable names with values from studentList
    for(int i=0;i<studentList.Count;i++) 
    {
        sqlCommand.Parameters.Add(firstVarName[i], SqlDbType.VarChar);
        sqlCommand.Parameters.Add(lastVarName[i], SqlDbType.VarChar);
        sqlCommand.Parameters[firstVarName[i]].Value = studentList[i].first;
        sqlCommand.Parameters[lastVarName[i]].Value = studentList[i].last;
    }

    using (SqlDataReader sqlReader = sqlCommand.ExecuteReader())
    { 
        if (sqlReader.HasRows)
            while (sqlReader.Read())
            {
                Console.WriteLine(sqlReader["firstName"].ToString());
                Console.WriteLine(sqlReader["lastName"].ToString());
            }
        else Console.WriteLine("No match.");
    }
}
为执行my demodata而添加的SqlParameters:

我曾经

public class Student { public string first; public string last; }


创建一些演示studen列表。

如果要检索所有学生的值,则需要在foreach Student循环中执行SQL:

但这真的没有多大意义。。。。你到底想达到什么目的??您可以按名字和姓氏进行搜索—这是从studentList中提供的—但是您也只输出检索到的名字和姓氏—这与您传入的名字和姓氏相同—那么为什么还要转到数据库呢


更新:正如@PatrickArtner正确评论的那样-创建和处理100个SqlDataReader实例并不理想。最好将此选择过程粘贴到一个存储过程中,使用一个SELECT和一个包含100个或更多学生ID或信息的存储过程,根据这些ID或信息选择学生,然后使用单个SqlDataReader对象在C中的存储过程中迭代结果集。

参数值是什么?向我们展示执行的sql…好吧,首先你要覆盖每个学生的参数值-但是搜索只执行一次,对于最后设置的值-所以sql当然只获取最后设置的值…这是一个例子,所以我知道如何通过比较names@PatrickArtner:不是理想的解决方案-只是试图向OP展示问题所在。当然,我更喜欢将这段代码粘贴到存储过程中,并传入一个表值参数以同时处理多个学生-使用一个SqlDataReader…@PatrickArtner您是对的,我没有想到这一点。您发布的解决方案是最好的方法吗?@Printer这是您问题的解决方案。这远远不是最好的——我可能不会一次按名字/名字查询100名学生——我要么使用ORM映射器并使用Linq to Sql进行筛选,要么在dbContext的结果上使用Linq to对象。我可能会得到所有+过滤器或一个我感兴趣的学生-取决于我的数据大小。我想如果你做你该做的事,你就有机会了。按照marc_的建议创建一个存储过程对我来说并不是第一个解决方案,但听起来很有趣,我没有发现这对夫妇没有将名字和姓氏联系起来。约翰·史密斯和拉里·约翰逊我不要拉里·史密斯。
public class Student { public string first; public string last; }
var studentList = Enumerable.Range(1, 20)
    .Select(i => new Student { first = $"firstname {i}", last = $"lastname {i}" })
    .ToList();
string selectQuery = "SELECT * FROM Students WHERE firstName = @first AND lastName = @last";

using (SqlCommand sqlCommand = new SqlCommand(selectQuery, sqlConnection))
{
    sqlCommand.Parameters.Add("@first", SqlDbType.VarChar);
    sqlCommand.Parameters.Add("@last", SqlDbType.VarChar);

    foreach (Student student in studentList)
    {
        sqlCommand.Parameters["@first"].Value = student.first;
        sqlCommand.Parameters["@last"].Value = student.last;

        using (SqlDataReader sqlReader = sqlCommand.ExecuteReader())
        {
             while (sqlReader.Read())
             {
                 Console.WriteLine(sqlReader["firstName"].ToString());
                 Console.WriteLine(sqlReader["lastName"].ToString());
             }
        }
    }
}