Monthly Archives: April 2014

MicroLite 5.0 Released

MicroLite 5.0.0 has been released on NuGet.

Changes/Enhancements

MicroLite 5.0 contains a number of changes and enhancements, many of which have been detailed in previous posts:

In addition to these, there are a number of internal changes to improve the performance of MicroLite and reduce its memory footprint.

Upgrading to 5.0

Firstly, if you didn’t use the new configuration method introduced in MicroLite 4.0.1 for configuring a connection, change to use it:

Configure.Fluently().ForMsSqlConnection("Connection").CreateSessionFactory();
Configure.Fluently().ForMySqlConnection("Connection").CreateSessionFactory();
Configure.Fluently().ForPostgreSqlConnection("Connection").CreateSessionFactory();
Configure.Fluently().ForSQLiteConnection("Connection").CreateSessionFactory();

Secondly, the SqlBuilder class has moved from MicroLite.Query to MicroLite.Builder so you will need to change any using MicroLite.Query; statements to using MicroLite.Builder; and any calls to MicroLite.Query.SqlBuilder to MicroLite.Builder.SqlBuilder if you have them fully qualified. A simple find and replace on “MicroLite.Query” to “MicroLite.Builder” should be sufficient.

Thirdly, the deprecated Projection(SqlQuery) method on IReadOnlySession/ISession has been removed, use Fetch<dynamic>(SqlQuery) instead as noted in MicroLite 4.0 – Changes to Projections and Dynamics.

The Wiki wiki page has also been improved with more details and examples – please check it out!

MicroLite 5.0 – String Handling

In .NET, strings are Unicode, however some databases have specific data types for strings which differentiate between ASCII and Unicode (e.g. in MS SQL Server VarChar being ASCII and NVarChar being Unicode).

If the database makes the distinction and the wrong type is used in a SQL command, it can result in poor performing queries (table scans over index lookups or unnecessary type conversion).

In MicroLite 5.0, the database connection/command handling has been exposed via a ‘database driver’. The new IDbDriver interface defines a HandleStringsAsUnicode property which is set to true by default but allows explicit control over whether strings are sent to the database as ASCII or Unicode (the default).

If you use MS SQL Server and the columns are NVarChar, HandleStringsAsUnicode should be left as true (the default value). If they are VarChar, HandleStringsAsUnicode should be set to false.

For other databases, refer to the documentation and if in doubt, leave it set to true.

If you need to, you can set HandleStringsAsUnicode to false when the session factory is created:

var sessionFactory = Configure.Fluently()
    .ForMsSqlConnection("Connection")
    .CreateSessionFacory();

// Only change this if you are sure you need to.
sessionFactory.DbDriver.HandleStringsAsUnicode = false;

MicroLite 5.0 – New Features

The last few posts have covered some of the changes coming in MicroLite 5.0, now that the major ones are covered let’s take a look at at some of the new features:

ObjectDelta

The ObjectDelta class and the ISession.Advanced.Update(ObjectDelta) add a neat way to perform partial updates against a database row.

// Firstly we need to instantiate a new ObjectDelta instance and 
// provide it with the class the update is targeted against and 
// the identifier value of the instance to update.
var objectDelta = new ObjectDelta(
    type: typeof(Customer), identifier: 12823);

// Then we can add a number of updates.
objectDelta.AddChange(propertyName: "Locked", newValue: 0);
...

using (var session = sessionFactory.OpenSession())
{
    using (var transaction = session.BeginTransaction())
    {
        // Apply the update and confirm if a record was updated.
        bool wasUpdated = session.Advanced.Update(objectDelta);

        transaction.Commit();
    }
}

UriTypeConverter

The type converter support has been increased by adding support for the System.Uri class. As before with the XDocument support in MicroLite 3.0.3, it’s as simple as setting the property type:

public class Thing
{
    public Uri Website { get; set; }
}

The conversion is managed by the MicroLite.TypeConverters.UriTypeConverter and is registered in the TypeConverter.Converters collection by default.

ConnectionScope

We have added finer control over when the connection to the database is opened and closed. The default behaviour matches MicroLite 4.0 and earlier which is to open a connection when a transaction is started and closed it when the transaction is completed.

However there may be times where you want to open the connection and close it when a session is opened and disposed (e.g. performing multiple transactions in a single session where it is more performant to hold a connection open or where you use SQLite in-memory databases where the database is deleted when the connection is closed).

In order to use it, call the overload on ISessionFactory when opening a session:

var session = sessionFactory.OpenSession(ConnectionScope.PerSession);

MicroLite 5.0 – Changes to Convention Mapping

In MicroLite 5.0, we are making further enhancements to the convention based mapping which provide even greater flexibility.

Convention Mapping History:

The changes in MicroLite 5.0 are as follows:

ResolveIdentifierStrategy

We have replaced the IdentifierStrategy property with the ResolveIdentifierStrategy method. This means that you no longer have to use the same IdentifierStrategy for every class (or that you can migrate from attribute mapping to convention mapping if this was preventing you from doing so).

By default it will return IdentifierStrategy.DbGenerated but you can override it if you want to specify a different strategy or calculate it based upon the type:

Configure.Extensions().WithConventionBasedMapping(
    new ConventionMappingSettings
    {
        ResolveIdentifierStrategy = (Type type) => 
        {
            if (type == typeof(MySpecialType))
            {
                return IdentifierStrategy.Assigned;
            }

            return IdentifierStrategy.DbGenerated; 
        }
    });

ResolveTableSchema

We have replaced the TableSchema property with the ResolveTableSchema method. This means that you no longer have to use the same schema for every class (or that you can migrate from attribute mapping to convention mapping if this was preventing you from doing so).

By default it will return null but you can override it if you want to specify a specific schema or calculate it based upon the type:

Configure.Extensions().WithConventionBasedMapping(
    new ConventionMappingSettings
    {
        ResolveTableSchema = (Type type) => 
        {
            if (type == typeof(MySpecialType))
            {
                return "MySpecialSchema";
            }

            return "dbo"; 
        }
    });

MicroLite 5.0 – Changes to Type Converters

In MicroLite 5.0, we have enhanced the Type Converters which we introduced in MicroLite 3.1.

The following method has been added to the interface:

object ConvertFromDbValue(IDataReader reader, int index, Type type);

This allows you to read the value from the IDataReader at the given index in the most efficient way (e.g. as an Int32 without the value being boxed).

From MicroLite 5.0, the full interface now looks like this:

ITypeConverter MicroLite 5.0

The ConvertFromDbValue(IDataReader, int, Type) is called when building an object from the results of a query, the ConvertFromDbValue(object, Type) method still exists but is only used when using ISession.Advanced.ExecuteScalar as there is no data reader used for that operation.