2017-08-30 41 views
0

我的问题已经修复,我的主要问题是从xAMl中的文本框中获取信息,该信息在该窗口关闭并且另一个打开后被擦除。虽然答案确实解决了我的其他问题,并使我的代码更加简单易读。非常感谢你!c#SqlDataReader未找到值

所以我目前正在为个人项目建立一个日历,并且正在致力于向数据库添加事件,Events的这个表存储两个varchars和一个int(名称,描述,用户ID),userid是一个外键并链接到用户表。当我使用下面的代码尝试并拉取用户输入的用户名时,它告诉我没有现有值。

using (SqlConnection connection = new SqlConnection()) 
     { 

      connection.ConnectionString = 
        "Data Source=calenderserver.database.windows.net;" + 
        "Initial Catalog=Calender;" + 
        "User id=*******;" + 
        "Password=*******;" + 
        "MultipleActiveResultSets = true"; 
      connection.Open(); 

      SqlCommand com = new SqlCommand("Select UserId from Users Where UserName = @user", connection); 
      com.Parameters.AddWithValue("@user", UsernameTextBox.Text); 

      SqlDataReader reader = com.ExecuteReader(); 
      reader.Read(); 
      int userid = reader.GetInt32(1); 

      messages.Text = "Event Added"; 
      SqlCommand command = new SqlCommand("INSERT INTO [Events] VALUES (@eventname, @eventdesc)", connection); 
      command.Parameters.AddWithValue("@eventname", name); 
      command.Parameters.AddWithValue("@eventdesc", description); 
      command.Parameters.AddWithValue("@userid", userid); 
      command.ExecuteNonQuery(); 

      reader.Close(); 
      connection.Close(); 

     } 

即使当我在实际SQL查询中运行相同的命令时,它也会返回正确的值。

SQL Command

我完全失去了这一点,并检查了多个来源和解决方案,将真正体会到了帮助。

+3

你可能想从连接删除您的数据库密码串在这个问题..... – MikeTheLiar

+0

你描述你的日历项目和事件表的很详细,但你的问题只引用您还没有描述的用户表... – Toastrackenigma

+0

@mikeTheLiar不要担心它是不是实际的帐户信息,但有人将其更改为*,这更好。 – RButler

回答

1

尝试使用ExecuteScalar函数。执行标量返回单个值,我看到您只需要用户标识。 看看这个link

int userid = (Int32)com.ExecuteScalar();

我希望它可以帮助!在GetInt32

+0

谢谢!它确实有帮助,我也很欣赏链接,这也有帮助! – RButler

1

指数从0开始为per doc,因此您的来电应改为:

int userid = reader.GetInt32(0); 
1

更改这些行:

 SqlDataReader reader = com.ExecuteReader(); 
     reader.Read(); 
     int userid = reader.GetInt32(1); 

到:

var userID = com.ExecuteScalar(); 

为什么:

当您的查询返回单个值时,应使用执行标量

Execute Reader以DataReader的形式返回数据的集合。 DataReader速度很快,您可以快速迭代它们以从数据库获取所需的数据。只要数据读取器处于打开状态,连接就会保持打开状态。

由于您只从数据库中获取单个值,因此使用ExecuteScalar是有意义的。这是更高效,也是重点。

如果您正在获取用户标识的列表,那么我建议您使用DataReader来遍历用户标识。

+1

不错,您提供的解决方案,但它会很好,如果您包括***为什么***切换到执行标量将解决问题。 –

+0

因为在他的问题,他的固定可见的用户名/密码,是一个更高的优先级;)但是真的,我要阐述 –

+0

如果在SQL表中的用户ID设置为自动增量将它仍然能够被称为? – RButler

2

你在做int userid = reader.GetInt32(1); get函数的索引是0,所以你实际上需要int userid = reader.GetInt32(0);所以你得到第一列。

话虽这么说,是因为你使用的是第一列的第一个结果,你可以从一个数据读取器开关简化代码使用ExecuteScalar()

 SqlCommand com = new SqlCommand("Select UserId from Users Where UserName = @user", connection); 
     com.Parameters.AddWithValue("@user", UsernameTextBox.Text); 

     int userid = (int)com.ExecuteScalar(); 
+0

谢谢!它帮助了很多!我只是在遇到另一个问题后才解决了我的问题,但它是你的和其他人评论类似的,如果解决方案不是相同的解决方案! – RButler