Tag Archives: Feedback

MicroLite Impresses Reviewer

The author of this post The Sorry State of .NET ORMs recently got in contact to let me know how impressed he was with MicroLite and that it came out top among all the ORMs he tested.

I won’t re-post his entire review, but here are a few points I appreciated:

MicroLite will actually not only configure much of its use by convention, but also will handle things like opening/closing connections for you, pooling your connections and much, much more.

It’s nice to see convention based mapping we added in an earlier version has helped reduce the setup of a new application and to understand some of the work MicroLite saves you from having to do yourself to get data between your application and database.

The documentation had me up and running in less than 10 minutes from knowing absolutely nothing about the lib

This is great! documentation is always the least fun thing to do as a developer and keeping it up to date and meaningful is always a challenge so it’s nice to know we’re doing a good job.

All in all, I have to admit to being very impressed.

Thank you!

Advertisements

MicroLite Comparison Feedback pt2

Following on from yesterdays post, I wanted to address this comment separately:

“PetaPoco just “feels” simpler to use and less like the clunky Spring/Hibernate syntax I wanted to avoid. But it doesn’t appear to be actively maintained. Then again, there are 500+ hits on Stackoverflow (always a useful measure 😉 ) for PetaPoco, and 6 for MicroLite.”

Ignoring the configuration element to MicroLite which we discussed in yesterdays post, how does it differ getting our database access?

// MicroLite
using (var session = sessionFactory.OpenSession())
{
    ...
}

// PetaPoco
using (var database = new Database("sqlite"))
{
    ...
}

OK, they’re pretty similar. How about using a transaction?

// MicroLite
using (var transaction = session.BeginTransaction())
{
    ...
    transaction.Complete();
}

// PetaPoco
using (var transaction = database.GetTransaction())
{
    ...
    transaction.Complete();
}

Again, almost identical.

Something that MicroLite offers is the option to override the IsolationLevel which by default is ReadCommitted.

// MicroLite
session.BeginTransaction(IsolationLevel.Serializable))

PetaPoco provides an alternative method for managing the transaction although I’m not sure what the difference is between them or why you need 2 ways to do the same thing.

// PetaPoco method 2
database.BeginTransaction();
...
database.CompleteTransaction();

Overall so far things are pretty similar. So how about the common methods used in most applications?

MicroLite 4.0.1
Delete Delete(object instance)
Delete(Type type, object identifier)
Insert Insert(object instance)
InsertOrUpdate(object instance)
Select (single) Single<T>(object identifier)
Single<T>(SqlQuery sqlQuery)
Select (many) Fetch<T>(SqlQuery sqlQuery)
Paged<T>(SqlQuery sqlQuery, PagingOptions pagingOptions)
Projection(SqlQuery sqlQuery)
Update Update(object instance)
InsertOrUpdate(object instance)
PetaPoco 5.0.1
Delete Delete(object poco)
Delete(string tableName, string primaryKeyName, object poco)
Delete(string tableName, string primaryKeyName, object poco, object primaryKeyValue)
Delete<T>(object pocoOrPrimaryKey)
Delete<T>(string sql, params object[] args)
Delete<T>(Sql sql)</code
Insert Insert(object poco)
Insert(string tableName, string primaryKeyName, object poco)
Insert(string tableName, string primaryKeyName, bool autoIncrement, object poco)
Save(object poco)
Save(string tableName, string primaryKeyName, object poco)
Select (single) Single<T>(object primaryKey)
Single<T>(string sql, params object[] args)
Single<T>(Sql sql)
SingleOrDefault<T>(object primaryKey)
SingleOrDefault<T>(string sql, params object[] args)
SingleOrDefault<T>(Sql sql)
First<T>(string sql, params object[] args)
First<T>(Sql sql)
FirstOrDefault<T>(string sql, params object[] args)
FirstOrDefault<T>(Sql sql)
Select (many) Fetch<T>(string sql, params object[] args)
Fetch<T>(Sql sql)
Fetch<T>(long page, long itemsPerPage, string sql, params object[] args)
Fetch<T>(long page, long itemsPerPage, Sql sql)
Fetch<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, string sql, params object[] args)
Fetch<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, Sql sql)
Fetch<T1, T2, T3, T4>(string sql, params object[] args)
Fetch<T1, T2, T3, T4>(Sql sql)
Fetch<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, string sql, params object[] args)
Fetch<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, Sql sql)
Fetch<T1, T2, T3>(string sql, params object[] args)
Fetch<T1, T2, T3>(Sql sql)
Fetch<T1, T2, TRet>(Func<T1, T2, TRet> cb, string sql, params object[] args)
Fetch<T1, T2, TRet>(Func<T1, T2, TRet> cb, Sql sql)
Fetch<T1, T2>(string sql, params object[] args)
Fetch<T1, T2>(Sql sql)
Page<T>(long page, long itemsPerPage, string sqlCount, object[] countArgs, string sqlPage, object[] pageArgs)
Page<T>(long page, long itemsPerPage, string sql, params object[] args)
Page<T>(long page, long itemsPerPage, Sql sql)
Page<T>(long page, long itemsPerPage, Sql sqlCount, Sql sqlPage)
Query<T>(string sql, params object[] args)
Query<T>(Sql sql)
Query<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, string sql, params object[] args)
Query<T1, T2, T3, T4, TRet>(Func<T1, T2, T3, T4, TRet> cb, Sql sql)
Query<T1, T2, T3, T4>(string sql, params object[] args)
Query<T1, T2, T3, T4>(Sql sql)
Query<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, string sql, params object[] args)
Query<T1, T2, T3, TRet>(Func<T1, T2, T3, TRet> cb, Sql sql)
Query<T1, T2, T3>(string sql, params object[] args)
Query<T1, T2, T3>(Sql sql)
Query<T1, T2, TRet>(Func<T1, T2, TRet> cb, string sql, params object[] args)
Query<T1, T2, TRet>(Func<T1, T2, TRet> cb, Sql sql)
Query<T1, T2>(string sql, params object[] args)
Query<T1, T2>(Sql sql)
Query<TRet>(Type[] types, object cb, string sql, params object[] args)
SkipTake<T>(long skip, long take, string sql, params object[] args)
SkipTake<T>(long skip, long take, Sql sql)
Update Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue)
Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue, IEnumerable columns)
Update(string tableName, string primaryKeyName, object poco)
Update(string tableName, string primaryKeyName, object poco, IEnumerable columns)
Update(object poco, IEnumerable columns)
Update(object poco)
Update(object poco, object primaryKeyValue)
Update(object poco, object primaryKeyValue, IEnumerable columns)
Update<T>(string sql, params object[] args)
Update<T>(Sql sql)
Save(object poco)
Save(string tableName, string primaryKeyName, object poco)

MicroLite has 2 methods for Delete, Insert, Select Single & Update and 3 for Select Many (arguably 2 since Projection has been obsoleted in favour of using Fetch<dynamic>).

PetaPoco however has 6 for Delete, 5 for Insert, 10 for Select Single, 12 for Update and a ridiculous 37 for Select Many! Maybe not simpler after all.

MicroLite Comparison Feedback

I stumbled across this Micro ORM Comparison and thought I’d post my thoughts.

The part about requiring more setup code is correct, whilst PetaPoco can be created as var db = new PetaPoco.Database("sqlite");. MicroLite requires you to create a session factory which in turn will create sessions.

Now it’s a fair point that we do need to write a few more lines of code to set up MicroLite, but it’s worth reviewing why that is. Firstly, you only need to write the setup code once in your application where the application actually starts (Global.asax/ App_Start for a web app or Program.cs for a windows forms/console app etc). Secondly, the actual MicroLite session is exposed via the ISession interface, this allows you to write nicely decoupled and testable code which is using MicroLite – something most other Micro ORM frameworks don’t enable.

The points about the convention based mapping are also worth considering – Yes the default conventions do expect the column names to match the property names (in casing as well). In the example, the foo class is cased using camelCasing rather than PascalCasing for the type name and properties which isn’t the capitalization convention used by the .NET framework. However it’s not so good if users feel that MicroLite is too rigid in this sense in preventing you from defining your own convention or tweaking the default convention as necessary.

The post was based on MicroLite 3.1.1, but it is worth mentioning that in MicroLite 4.0 we introduced much greater control over the conventions so for the example you could leave the database and class casing as camelCase and then override the IsIdentifier method in the convention settings:

new ConventionMappingSettings
{
    // Provide a custom method which checks if the property name
    // is lower case 'id'.
    IsIdentifier = (PropertyInfo propertyInfo) => 
    { 
        return propertyInfo.Name == “id”; 
    }
}

The functionality that MicroLite offers above basic CRUD operations are also worth considering if you are considering Micro ORM frameworks:

  • An API to include additional queries in a single database call.
  • A powerful fluent Sql Builder to build more complex queries at runtime.
  • The ability to Intercept Delete, Insert and Update calls via the IListener interface.
  • The ability to create custom Type converters via the ITypeConverter interface.
  • Custom extensions for ASP.NET MVC and WebAPI.
  • Integration with Log4Net or NLog if you want any log data from MicroLite to be written to your application log and you use either framework (to the flexibility to create your own logging extension)
  • A compiled help file and rich xml documentation for tool tips in Visual Studio.

There’s also the question of performance which I’ll cover in another post.