Search code examples
c#.net.net-3.5data-access-layersqlcommand

C# abstraction and database layer and delegates


Could I get some help explaining this answer below and how it works with the delegate. Its the answer from here: C# abstraction and database layer

...if you are stuck on the idea of using a DataReader, you could pass a delegate to the helper, which gets invoked inside of the using statements:

public string GetMySpecId(string dataId)
{
    return _dbHelper.ExecuteQuery(
        dr => 
           {
               if(dr.Read())
               {
                   return dr[0].ToString();
               }
               // do whatever makes sense here.
           },
        @"select ""specId"" from ""MyTable"" where ""dataId"" = :dataId",
        new SqlParameter("dataId", dataId));
    return result.Rows[0][0].ToString();
}

You could also use a lightweight tool like Dapper to simplify some of the syntax and take care of mapping to your data types. (You'd still need to deal with opening a connection and such.)


Solution

  • Declaring the ExecuteQuery Method from above should look something like this:

    public DataTable ExecuteQuery(Func<DataReader, DataTable> delegateMethod, string sqlQuery, SqlParameter param)
        {
            using (SqlConnection conn = new SqlConnection(this.MyConnectionString))
            {
                conn.Open();
    
                // Declare the parameter in the query string
                using (SqlCommand command = new SqlCommand(sqlQuery, conn))
                {
                    // Now add the parameter to the parameter collection of the command specifying its type.
                    command.Parameters.Add(param);
    
                    command.Prepare();
    
                    // Now, add a value to it and later execute the command as usual.
                    command.Parameters[0].Value = dataId;
    
    
                    using (SqlDataReader dr = command.ExecuteReader())
                    {
                       return delegateMethod(dr);
                    }
                }
            }
        }
    

    That should be right, you may have to swap the DataReader and the DataTable in the Func, I can't remember which comes first the param types or the return type.

    Here's another example of using the Func delegate, there's also the Action Delegate if you don't need a return type.

    Func Delegate Reading Normal Delegate Reading