0

I have been trying my hand at writing the connecting code to connect with the database. It's been going pretty well, but I ran into a strange problem that I cant seem to fix.

When I try to add a parameter to my query it doesn't retrieve the data. But when I switch out the parameter it does retrieve the correct data.

The data access layer looks like this. (I know it is very insecure but I'm just getting started):

public static class UserDA
{
    private static MySqlCommand cmd = null;
    private static DataTable dt;
    private static MySqlDataAdapter da;

    public static User RetrieveUser(String username)
    {
        // Create the query
        const String query = "SELECT `Username`, `Password` FROM login WHERE `Username` = '@Username';";
        cmd = DbHelper.Select(
            query, 
            new Dictionary<String, String> 
            {
                {"@Username", username}
            });

        //Setup model
        User user = null;
        if (cmd == null) return null;

        // Get the data and add it to the user model
        dt = new DataTable();
        da = new MySqlDataAdapter(cmd);
        da.Fill(dt);
        foreach (DataRow dataRow in dt.Rows)
        {
            user = new Models.User(
                dataRow["Username"].ToString(),
                dataRow["Password"].ToString());
        }

        return user;
    }
}

And the Select method looks like this:

public static class DbHelper
{
    private static MySqlConnection _connection;
    private static MySqlCommand _cmd;
    private static DataTable _dataTable;
    private static MySqlDataAdapter _adapter;

    public static void EstablishConnection()
    {
        // Gets a connection to the database. Code works.
    }

    /// <summary>
    /// Give the query and a dict with the param name and value
    /// </summary>
    public static MySqlCommand Select(String query, Dictionary<String , String> param)
    {
        try
        {
            if (_connection != null)
            {
                _connection.Open();
                _cmd = _connection.CreateCommand();
                _cmd.CommandType = CommandType.Text;
                _cmd.CommandText = query;
                foreach (KeyValuePair<String, String> keyValuePair in param)
                {
                    _cmd.Parameters.AddWithValue(keyValuePair.Key, keyValuePair.Value);
                }

                _cmd.ExecuteScalar();
                _connection.Close();
            }
        }
        catch (Exception e)
        {
            _connection?.Close();
        }
        return _cmd;
    }
}

And then finally the user model:

public class User
{
    public String Username;
    public String Password;

    public User(String username = "", String password = "")
    {
        Username = username;
        Password = password;
    }
}

The problem happens when I try to get the data from it. If I use the select query with the parameter it does not work, but as soon as I change the parameter to the actual value it retrieves it just fine. I am really scratching my head at this point. Did I forget a step somewhere?

Thanks!

4
  • 1
    private static MySqlConnection _connection; is a bug waiting to happen. You may not share MySqlConnection objects across threads: mysqlconnector.net/troubleshooting/connection-reuse Instead, they're pretty cheap to create (due to connection pooling) so just create a new one whenever you need one. Also use a using statement (using (var connection = new MySqlConnection(connectionString)) { ... } and you can remove the explicit calls to Close (and the exception handler); it will be closed automatically. Commented Oct 31, 2020 at 17:30
  • 1
    Finally, libraries like stackexchange.github.io/Dapper have already written all this code for you; I would strongly recommend using an off-the-shelf solution instead of trying to write your own. Commented Oct 31, 2020 at 17:31
  • I shall defiantly have a look at the library. Still I want to make my own one first as it is a learning tool for me atm. First time I am really writing a connector in c#. Only done it in php before now. Commented Nov 3, 2020 at 0:02
  • yep, writing the code yourself is a fantastic way to learn how ADO.NET works, and understand what Dapper is doing under the hood. Commented Nov 3, 2020 at 0:59

2 Answers 2

3

Try removing the quotation marks around @Username in your SQL code.

Before

SELECT `Username`, `Password` FROM login WHERE `Username` = '@Username';

After

SELECT `Username`, `Password` FROM login WHERE `Username` = @Username;

If that doesn't work, try changing your dictionary from <String, String> to <string, string>.

Sign up to request clarification or add additional context in comments.

Comments

0

Remove this from your code

  _cmd.ExecuteScalar();
                _connection.Close();

and just for the better coding style I higly recomend to change class User to

public class User
{
    public string Username {get; set;}
    public string Password {get; set;}

 public User()
{
}
    public User(string username, string password)
    {
        Username = username;
        Password = password;
    }
}
```

7 Comments

I agree with the coding style for users, but why would I remove _cmd.ExecuteScalar(); and _connection.Close();. Thats the whole thing getting the data. Or do you mean that I should move it to the place I am actualy running the code?
I mean I don't understand why are running cmd if you dont get any data? And you can't use cmd object when the connection is closed. And It's a bad practice to use adapter to read some data. Much more efficient to use datareader.
So I should be using _cmd.ExecuteReader(); and returning the dataReader and use that.
It works only for desctop applications when you keep adapter in your computer memory. Nobody uses adapter for a web application. Server dispose all data after sending response.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.