Installation

Nuget package url: https://www.nuget.org/packages/MySql.Simple/ On the package manager console enter:

Install-Package MySql.Simple

Connecting to a database

In order to set up a new connection, you will need to create a new instance of Mysql.Simple.Database by providing the connection string. Since the Database class allows an implicit operator for the connection string, you can directly pass the connection string without a constructor to create a new Database connection. The following is an example of a connection string and creating a new insance of a database.


    string ConnectionString = "Server=;Uid=;Database=;password=;SslMode=none";

    Database db = ConnectionString;

However for readability, if needed, there is always the option to use the constructor with the connection as a parameter as follows:


    Database db = new Database(ConnectionString);

The database object contains an object of MySql.Data's MySqlConnection that has been connected with the connection string. If required, this object can be accessed by the help of an implicit conversion or by using the Connection property. The two lines below help fetch the same object in two different ways.


    MySqlConnection conn1 = db;

    var conn2 = db.Connection;

The database object also implements IDisposable. On dispose, it closes the connection and disposes the MySqlConnection object. Hence this object can be created with using to ensure that the connection is closed and the object is disposed.


        using (Database db = ConnectionString)
        {
            
        }

Quering

There are four ways (four functions) queries can be excuted. These are similar to those of Webmatrix.Data. All four of these function support a syntax that simplifies the usage of String.Format when calling the function. So instead of using: (String.Format("INSERT INTO User (Username, FirstName) Values ('{0}', '{1}')", Username, Firstname)) you could simply do:("INSERT INTO User (Username, FirstName) Values ('@0', '@1')", Username, Firstname). Note that @0 and @1 are @ followed by the index of the params. So @0 refers to the param at index 0 which is 'Username'.

The following are the four different ways to execute sqls.

Simply execute a query (no output)

To directly execute a query you can simply call the .Execute() method in the Database object. This would return an int that specifies the number of rows effected in the database.

        int RowsEffected = db.Execute("INSERT INTO Users (Username, FirstName) Values ('@0', '@1')", Username, Firstname);

Run query to get a single value output

To get just a single value as an output, use the .QueryValue() method of the Database object. This function would return the first column of the first row of the result of the query.



    using (var result = db.QueryValue("SELECT COUNT(ID) FROM Users"){

        // setting to an existing variable with the same datatype
        User user = new User(){
            ID = result;
        };

        // or directly returning assuming the return type is the same as the datatype
        return result;
    }

Run query to get an entire row

To fetch a entire row, use the function .QuerySingle(). This function returns an object of the class MySql.Simple.QueryResult. This object contains and uses an object of MySql.Data.MySqlDataReader. Since this object implements disposable, it can be used with using. The dispose function disposes the MySqlDataReader object. Once you fetch the QueryResult object, you can use this object to access columns of the row by the column name or index.


    using (var result = db.QuerySingle("SELECT * FROM User WHERE ID = @0", ID))
    {
        
        if (result){ // check if a row was returned. avoid if you are sure the query returns atleast one row
           User user = new User(){
                ID = result["ID"],
                UserName = result["username"],
                FirstName = result["FirstName"],
                LastName = result["LastName"],
                DateOfBirth = result["DateOfBirth"]
            };
        }

        
    }    

In the above code, note that once the value of the column is fetched, when it is being assigned to a variable, it returns in the same type as the variable it is being assigned to. For instance user.ID is an int. So result["ID"] returns an int. Since UserName is a string, result["username"] will also return string. Since DateOfBirth is of type DateTime, result["DateOfBirth"] returns DateTime. Note that all these assignments directly use implisit operators and the functions of MySqlDataReader, .GetInt32(), .GetString() and .getDateTime() respectively. In other words these operation have no performance issues as compared to directly using these functions. These assignments are compatable with every primitive datatypes and with the types MySqlDateTime, MySqlDecimal and MySqlGeometry.

If you require to use the reader object within the result object, you can either use the implicit converter or the property reader.The two lines below help fetch the same object in two different ways.


    MySqlDataReader reader1 = result;

    var reader2 = result.reader;

Using a query to fetch multiple rows

Fetching multiple rows can be done with the Query() function. The process is very similar to using QuerySingle. The main difference between the two is looping. In order to loop the result, the result..Read() function is called which gets each line and returns a boolean (false if empty).


   using (var result = db.Query("SELECT username, FName, LName FROM tblUsers"))
   {
       while (result.Read())
       {
           users.Add(new TUser() {
              UserName = result["username"],
              FName = result["FName"],
              LName = result["LName"],
              DateOfBirth = result["DateOfBirth"]
           });
       }
   } 

Code friendly quering

The database object also has functions to execute code friendly sql. That is instead of adding entire large queries into one string without any syntax lighliting and later looking for the different parts of your sql, there are functions to run almost all kinds of queries to make the sql commmands more readable in the code. All these functions can be followed by the four functions mentioned above: Query(), QuerySingle(), QueryValue() and Query().

Select function



    db.Select("id, fname", "lname")
        .From("user u")
        .Join("entries e", "u.id = e.userID")
        .Where("username LIKE $0", query)
        .Order("fname")
        .Limit(20)
        .Query();


Debug functionality

For debugging porpose, a property 'FullQuery' is provided that can be used in place of the four functions. This property provides the exact query that would be executed when the chained functions run.



    string sql =
    db.Select("id, fname", "lname")
        .From("user u")
        .Join("entries e", "u.id = e.userID")
        .Where("username LIKE $0", query)
        .Order("fname")
        .Limit(20)
        .FullQuery;


Or to reuse the query, the following code such as the following can be used:



    var q = db.Select("id, fname", "lname")
        .From("user u")
        .Join("entries e", "u.id = e.userID")
        .Where("username LIKE $0", query)
        .Order("fname")
        .Limit(20);

    string sql = q.FullQuery;
    using (var users = q.Query());

Advanced Conditions

If the where clause is complex with nested conditions, functionalities for convenient management are provided. These can be used in the where clause inside under the select and update functions.

First You will need to create the conditions. Creating a condition can be done as follows.


    var cond = Conditioner.Build("name LIKE $0", name);  // the usual format with the object(s)
    var cond2 = Conditioner.Build("fname = $0", fname);  // the usual format with the object(s)
    var cond3 = Conditioner.Build("lname", lname);  // with no $ or @, automatically converts to "lname = 'lame'" if lname were 'lame'
    var cond4 = Conditioner.Build("fname = lname"); // without any object

To simplify the condition creations, you can take the help of the Conditioner class


    Conditioner c = new Conditioner(); // creates a helper object

    // now the same above code can be written with the helper object c
    var cond = c["name LIKE $0", name]; 
    var cond2 = c["fname = $0", fname]; 
    var cond3 = c["id", id];  
    var cond4 = c["fname = lname"];

Now these conditions can be uses in complex conditional statments as follows


    .WhereConditional(cond.And(cond2.Or(cond3).And(Cond4)));

Or now you can use it as follows


    .WhereConditional(cond & (cond2 ! cond3 & Cond4));