I’ve received a few questions since I first released MicroLite so I thought I’d post some of the common ones along with my answers to them.
Why do I have to write SQL queries instead of using Linq?
The main reason is to avoid the translation of a Linq expression into SQL. The DSL (Domain Specific Language) for databases is SQL so it makes sense to just write SQL in the first place. Additionally, Linq expressions are complex and trying to cover all possibilities would be impractical which means you would need the ability to use native SQL anyway.
“If you wanted to ask an Italian friend a question, would you write it in French first and then translate it into Italian?”
Why is there no method on SqlBuilder to do SELECT TOP N?
Originally I planned to add one but as I thought about it further, I realised it’s unnecessary. We can do TOP queries already by writing a standard select statement and using
ISession.Paged (if you want the top (first) 20 results for a query, just use
ISession.Paged(sqlQuery, page: 1, resultsPerPage: 20) instead).
Why have a separate Configuration class?
I wanted to be able to provide fluent APIs where possible to make it easy to understand what methods should be called and when. It also gives us a central place to add configuration options in future (like when the
Configure.Extensions were added). It also moves the concern of configuration into a specific place, rather than being another set of methods on the ISession.
Why use interfaces for the API?
The public API for MicroLite is based around abstractions, the reason for this is so that callers are not bound to implementations. This makes it easier to do things like unit testing as the interfaces can be replaced with Mocks or Fakes. The exceptions to this are simple classes which only operate on their own data like
Why do I have to use attributes to map classes?
I wanted MicroLite to be explicit about what it is doing and how it is used, the opt-in model of the attribute mapping makes it easy to understand how a class relates to a table. However one of the other key principles is that MicroLite should be extensible, so you can actually implement your own mapping convention if you don’t want to use attributes.
Why is the SqlDialect specified as a string instead of an enum in the configuration?
This is because MicroLite is designed for extension, although in MicroLite 2.1 the
SqlDialect concept is internal, in version 3 I intend to make it public and allow people to create their own
SqlDialect to add support for other databases. If an enum was used for the
SqlDialect, other users could not add a value to it which would make it hard to register other dialects.
Should I implement the repository pattern when using MicroLite?
I would advise against it, treat MicroLite as a generic repository and just give it the relevant
SqlQuery for the results you want. You will end up creating a lot of unnecessary classes if you create a repository for each class you use and make it a lot harder to use some of the benefits of MicroLite such as the includes. The repository pattern is useful to abstract database persistence or encapsulate a database API which cannot be tested, however MicroLite already does the former and is designed with testability in mind anyway.
Since there is no lazy loading, how should I use MicroLite in a screen where I need to show multiple types of data?
The Includes functionality introduced in MicroLite 2.0 is designed to help solve this issue.
For example, if you are creating an application using the MVVM pattern, the ViewModel should encapsulate the
ISession and expose properties for each object or collection related to the root entity (for example the CustomerViewModel may have a collection of Invoices or Orders in addition to the Customer data.
Why would I use MicroLite instead of another Micro ORM?
MicroLite was built to be simple to use, easily tested and extensible. If any of these matter to you then it’s worth investigating the other features to see if it’s suitable for your application. MicroLite tries to be explicit about its behaviour and since it is not built around dynamic objects you still get good tooling support from intelisense and xml documentation.