C#如何将sql数据库中的值存储到对象

时间:2018-02-03 16:09:04

标签: c# sql-server

每当验证正确或等于1时我都有一个登录页面我想将它传递给下一个窗口,但我的问题是我无法将值存储到我创建的类对象中。

这个想法是,如果usernamepassword是正确的,那么我想将它们的值存储到一个对象中,这样我就可以将它传递给下一个窗口并重用它。关于分离它们的提示也很好。抱歉,我很蠢,刚刚两周前开始使用C#。

// logging-in process codes
private void LoggingIn()
{
    SqlConnection sqlCon = new SqlConnection(@"Data Source=localhost\SQLEXPRESS; Initial Catalog=SalesDB; Integrated Security=true;"); // this is the connection to the database

    try
    {
        if (sqlCon.State == ConnectionState.Closed)
        {
            sqlCon.Open();
        }

        String query = "SELECT COUNT(1) FROM users_tbl WHERE Username = @Username AND Password = @Password";
        SqlCommand sqlCmd = new SqlCommand(query, sqlCon);
        sqlCmd.CommandType = CommandType.Text;

        sqlCmd.Parameters.AddWithValue("@Username", txtUsername.Text);
        sqlCmd.Parameters.AddWithValue("@Password", txtPassword.Password);

        int count = Convert.ToInt32(sqlCmd.ExecuteScalar()); //if true the value will be converted to "1" in integer.
        LoginInfo userInfo = new LoginInfo();

        using (SqlDataReader oReader = sqlCmd.ExecuteReader())
        {
            while (oReader.Read())
            {
                userInfo.UserName = oReader["Username"].ToString();
                userInfo.PassWord = oReader["Password"].ToString();
                userInfo.Role = oReader["Role"].ToString();
                userInfo.FirstName = oReader["First_Name"].ToString();
                userInfo.LastName = oReader["Last_Name"].ToString();
            }
        }

        if (count == 1)
        {
            MainWindow dashboard = new MainWindow();
            dashboard.Show();
            this.Close();
        }
        else
        {
            MessageBox.Show("Username or Password is incorrect. ");
            txtUsername.Focus();
            txtUsername.Clear();
            txtPassword.Clear();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    finally
    {
        sqlCon.Close();
    }
}

// login button code
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
    LoggingIn();
}

// my LoginInfo Class
namespace TestApp
{
    public class LoginInfo
    {
        private string userName;

        public string UserName
        {
            get { return userName; }
            set { userName = value; }
        }

        private string passWord;

        public string PassWord
        {
            get { return passWord; }
            set { passWord = value; }
        }

        private string role;

        public string Role
        {
            get { return role; }
            set { role = value; }
        }


        private string firstName;

        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }


        private string lastName;

        public string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }
    }
}

3 个答案:

答案 0 :(得分:1)

我建议您不要管理自己的用户帐户。有很多好的选择可以帮到你。如果您希望将它们存储在本地,我建议您查看Microsoft Identity。如果您在创建新项目时选择它,Visual Studio 2017将为您设置如果您选择自己管理用户帐户,您将需要加密它们。最常被接受的方法是在数据库中存储单向散列。这样,如果黑客入侵您的数据库,他们就无法读取密码。 https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?tabs=visual-studio%2Caspnetcore2x

此外,如果您正在访问数据库,则可以检查Microsoft Entity Framework。它将有效地将您的数据库映射到您的对象。

免费提供许多优秀的学习资源。 Youtube将是一个很好的起点。执行搜索时,请确保包含您正在使用的.Net Framework版本,以便获得相关结果。祝好运! (我本来只是评论了这个而不是答案,但我还没有获得这种特权)

答案 1 :(得分:0)

我没看到在读取SqlReader对象的数据时你是如何得到sql异常的。

请参阅以下代码:

int count = Convert.ToInt32(sqlCmd.ExecuteScalar()); //if true the value will be converted to "1" in integer.
LoginInfo userInfo = new LoginInfo();

using (SqlDataReader oReader = sqlCmd.ExecuteReader())
{
     while (oReader.Read())
      {
          userInfo.UserName = oReader["Username"].ToString();
          userInfo.PassWord = oReader["Password"].ToString();
          userInfo.Role = oReader["Role"].ToString();
          userInfo.FirstName = oReader["First_Name"].ToString();
          userInfo.LastName = oReader["Last_Name"].ToString();
      }
}

上面的代码出了什么问题?

  1. using{}的{​​{1}}条款之前,应该有SqlDataReader
  2. 分配新的sql命令以从数据库中获取用户数据
  3. 而不是在您需要new sqlCmd
  4. if(oReader.Read())

    之前添加此内容
    using{SqlDataReader

    上面的代码将获取query = "SELECT [username], [password], First_Name, Last_Name FROM users_tbl WHERE Username = @Username AND Password = @Password"; sqlCmd = new SqlCommand(query, sqlCon); sqlCmd.CommandType = CommandType.Text; sqlCmd.Parameters.AddWithValue("@Username", txtUsername.Text); sqlCmd.Parameters.AddWithValue("@Password", txtPassword.Password); 所需的数据,然后它将读取它。

      

    您还可以将两个Sql查询组合为对数据库的单个调用。如果sqlReader读取任何内容,只需获取用户详细信息并将布尔标志设置为true。然后检查boolean varable而不是检查if(count == 1)。留给你试试

答案 2 :(得分:0)

据我所知,你基本上想要一个可以从任何类访问的全局对象。我不会进入你的sql查询或上面的其他代码。

首先创建一个公共静态类并为它们提供一些静态属性。

public static class UserInfoObject
    {
        public static int CountFromYourQuery { get; set; } = 0; //I would initiate the value to 0
        public static string UserName { get; set; } = ""; //added this one so that you understand the structure or you realise that you can add more properties this way
    }

现在,您可以从项目中的任何位置(当然)调用此类及其属性。但是在打电话之前你必须先进行初始化。

private UserInfoObject UIO = new UserInfoObject(); // this initialised your class with initial value.

现在您可以将值插入其属性

if (count == 1)
        {
           UIO.CountFromYourQuery = YourCountVariable;

            MainWindow dashboard = new MainWindow();
            dashboard.Show();
            this.Close();
        }
        else
        {
        ...
        }

抱歉,我刚刚意识到你实际上已经完成了所有这些,但是你的类没有静态属性,这就是为什么你不能像全局那样访问它们。

我仍然希望我上面的例子可以帮助你理解这里发生的事情。 你也可以用简短的方式写{get; set;},除非你在getter或setter中处理任何东西。

PS:我不是C#的专家,所以我的代码练习可能看起来不专业。此外,您在编写代码时应考虑内存消耗/资源阻塞,尤其是静态变量,这些变量将长时间保留在内存中。

希望这会有所帮助:)