Project Description

Kerosene is a self-adaptive and configuration-less ORM library, with a SQL syntax based on C# dynamics, WCF, and Entity Framework capabilities for POCO objects.

RELEASE NOTES
  • Oct 10, 2012: New maintenance version 5.3.2 is now available to include extension methods that permits an easy chaining of the ConvertBy() mechanism to retrieve in an structured way the converted business objects from your database.

Why Kerosene

Because there are lot of scenarios where the overhead, time and efforts you need to devote to master, write and maintain the plethora of things most ORM solutions require don't really worth. Just consider:
  • They tend to be complex environments, hard to understand and operate with. They require you to master a whole range of tools, configuration files, and languages, just to begin being productive. And the simpliest solution easily becomes hard to maintain, even if you are using automatic code generation tools.
  • They typically require you to modify your business classes. Even if those modifications are in the form of attributes they break, in my modest opinion, the principle of separation of concerns. It can be worse if you don't have access to their source code, what happens very often, and eventually force you to write wrapper classes, struggling to maintain the overal coherence.
  • They typically provide you not very much control on the actual SQL code they generate, ending up executing really fat code. Not to mention you need either need to write your commands in plain text or either follow the strict C# syntax, instead of using the more flexible SQL one.
  • And, finally, the hidden assumption that you have a stable and controlled environment, all from the database's schema to those configuration files, because as soon as the tiniest piece change you will need to recreate them all and pray that no changes will break your solution.

Kerosene has been built to deal with those scenarios and much more. It provides you with a self-adaptive and configuration-less solution that will adapt to whatever schema your database has or is returned from your database, without requiring you to maintain any configuration files or to polute your POCO business classes with any attribute. You can use a natural SQL-like syntax from your C# code, even when the compiler is not supposed to support it. And you have full control on what code is produced and executed against the database.

Built to be easy to use

Using Kerosene is extremely easy. It has been designed on purpose to let you forget all those details and nuances that, otherwise, you have to take into consideration when using other ORMs. And to be flexible enough to adapt to whatever scenario it may have to face, even those where you only have minimal information available about the database.

For instance, suppose you only know your database has a table named "Employees" with a column named "LastName", and that you are interested in obtaining a list of all the employees whose last name starts with "C" or bigger. What follows is all what you need to write:

var link = new KLinkDirectSQL( "... your connection string here ..." );
var cmd = link.From( x => x.Employees ).Where( x => x.LastName >= "C" );
foreach( var obj in cmd ) Console.WriteLine( "Returned record: {0}", obj );

Yes, that’s right! No external configuration or mapping files. No detailed knowledge of your database’s schema. No modifications of any business class or write any wrappers. We have been able to use a SQL-like syntax that has even allowed us to compare two string-alike elements using regular C# operators (something not even supported by the C# compiler). And, on of top of that, as expected, no need to worry about creating, opening, and closing any connections to the database.

By default those contents are returned in the form of instances of the class "KRecord", a dynamic object that will adapt itself to whatever schema is produced as the result of the execution of your command. If you want to convert these records into instances of your business classes, Kerosene provides you two mechanisms. The first one, used with this "Core" mode, permits you to specify the specific the conversions you wish to use with each command. For instance:

foreach( var obj in cmd.ConvertBy( rec => {
   dynamic x = rec;
   return new {
      x.Id,
      Name = string.Format( "{0}, {1}", x.LastName, rec[ "FirstName" ]
   };
} ) ) Console.WriteLine( "Converted record: {0}", obj );

This example also shows two ways to access the contents (columns) in the records: either by using a dynamic syntax or by using an indexed one. The first one is easy and handy and takes care of type conversions on your behalf. The second one is slightly faster, but it might require a bit of manual code if complex type conversions are involved.

The standard operations are also very easy to use. For instance, to create and later delete an Employee, you can just write what follows:

link.Insert( x => x.Employees ).Column(
   x => x.Id = "007",
   x => x.FirstName = "James",
   x => x.LastName = "Bond",
   x => x.CountryId = "uk" 
).Execute();

link.Delete( x => x.Employees ).Where( x => x.Id == "007" ).Execute();

The documentation provides more examples and insights on how to use this "Core" mode in more demanding scenarios: Kerosene Basics.

An Entity Framework for your POCO classes

But you may want to focus on your business classes instead of dealing with the database-oriented nature of the "Core" mode. For this scenarios Kerosene provides you the "Maps" mechanism, an Entity Framework alike capability specifically designed to be used with POCO classes.

Let me reinforce this: you don't have to alter your business classes in any way. Not even with attributes or wrapper classes (you may not even have access to their source code) and, of course, following the principles of Kerosene, you don't have to write any configuration files.

It is also designed to be extremely easy to use. Continuing with our previous example, to find a given Employee you just need to write what follows:

var map = new KMap<Employee>( link, x => x.Employees );
Employee emp = link.Find<Employee>( x => x.Id == "007" );

It works by creating a "map" between your business type and a specific primary table in your database. By default, the maps use a bit of reflection at the time when they are created so that they can be used later in most scenarios without any further customization.

They also permit you to focus on your business problem and to forget the database related stuff. You can create and manipulate your instances they way you like, and only when your are done with them access the database:

Employee emp = new Employee() { Id = "007", FirstName = "James", LastName = "Bond", CountryId = "uk" };
... // Your application's stuff

link.Insert( emp ).Execute();
... // More stuff

link.Delete( emp ).Execute();

The documentation shows how to customize this mechanism to deal with, for instance, dependencies with other business classes, or other more advanced scenarios: Kerosene Maps.

What the library includes

This is the fifth incarnation of the Kerosene ORM project. It comes with the following elements:
  • An agnostic "Core" framework able to work with whatever database is supported by the underlying ADO.NET mechanism (yes, it makes no sense to reinvent the wheel).
  • An adaptation for Microsoft SQL Server databases.
  • The "Maps" Entity Framework described before.
  • A specific version for WCF scenarios, that let you use Kerosene as a client for a Kerosene server, without any knowledge of what physical database the remote server is using, if any.

Help needed

Contributions are needed for the following sub-projects:
  • Adaptation for Oracle databases. If you have available an Oracle environment it should be a matter of just following the included example for Microsoft SQL databases.
  • The same for MySQL databases.
  • The same for Progress databases.
  • An adaptation for Azure environments. Most probably it will be a mixture of the example for MS SQL databases with the adaptation for WCF scenarios, but it is just my initial take...

I'll be happy to provide support and/or to participate in any of those, or any other one you may feel like.

Last edited Oct 10, 2012 at 10:54 AM by mbarbac, version 18