Search code examples
c#mysqlbinary.net-2.0parameterized-query

how to pass objects (byte array) in query if query is not parameterized?


I have this query to be run:

string query = @"SELECT *
                 FROM   hint 
                 WHERE  addedSessionId IN (x, y, z, ............)";


if (_connSource.State != ConnectionState.Open)
    _connSource.Open();

MySqlCommand cmd = new MySqlCommand(query, _connSource);
MySqlDataReader r = cmd.ExecuteReader();

List<Hint> lstHint = new List<Hint>();
while (r.Read())
{
    Hint h = new Hint(Convert.ToInt32(r[0]), Convert.ToInt32(r[1]), 
                      Convert.ToString(r[2]), Convert.ToInt32(r[3]), 
                      Convert.ToInt32(r[4]));
    h.addedSessionId = (Guid)r[5];

    lstHint.Add(h);
}

r.Close(); //important

In the above code, how do I pass values x, y, z etc into the query itself? x, y, z etc are not int or string but byte arrays. In my code they are .net Guid fields, but I'm saving it in db as binary values by converting it to byte arrays.

I can achieve what I want by doing this in parameterized way as shown below:

string query = @"SELECT *
                 FROM   hint 
                 WHERE  addedSessionId = @newSessionId";


if (_connSource.State != ConnectionState.Open)
    _connSource.Open();

List<Hint> lstHint = new List<Hint>();
foreach (List<Guid> myGuid in lstGuid)
{
    MySqlCommand cmd = new MySqlCommand(query, _connSource);
    cmd.Parameters.AddWithValue("newSessionId", myGuid.ToByteArray());
    MySqlDataReader r = cmd.ExecuteReader();

    while (r.Read())
    {
        int id = Convert.ToInt32(r[0]);

        if (IsThisEntryAlreadyAdded(id, lstHint))
            continue;

        Hint h = new Hint(id, Convert.ToInt32(r[1]),
                          Convert.ToString(r[2]), Convert.ToInt32(r[3]),
                          Convert.ToInt32(r[4]));
        h.addedSessionId = (Guid)r[5];

        lstHint.Add(h);
    }

    r.Close(); //important
}

The problem with the 2nd approach is that its terribly slower comparatively. Here not only query has to be run to database a lot more times, but also each time I need to ensure if that particular entry is not already added by running this IsThisEntryAlreadyAdded function.

My question is how to pass objects (in my case byte arrays) in non-parametrized queries? If its impossible, my question is is there an alternative to make my query faster?


Solution

  • Here is sample(not tested just pseudo code) how I imagine this could be done:

    string query = @"SELECT * FROM   hint  WHERE  addedSessionId IN (";
    MySqlCommand cmd = new MySqlCommand(query, _connSource);
    int i = 0;
    foreach (List<Guid> myGuid in lstGuid)
    {
        query = string.Format("{0}@param{1}", query, i);
        cmd.Parameters.AddWithValue(string.Format("@param{0}", i), myGuid.ToByteArray());
        i++;
        if(i != lstGuid.Count) query = string.Format("{0},", query);
    }
    query = string.Format("{0})", query);
    cmd.CommandText = query;
    //Here you have command with constructed query and params