This project is read-only.

Part 1. What's the ORM? Blog in broken English.

Oct 15, 2009 at 10:51 AM

 

Disclaimer.

At first, sorry for my English and possible grammar mistakes.

All things described here is my opinion and may be incorrect.

 


 

 

This is the first post in the series of post where I want to share my thinking about the ORM, life, programming and other things. In this series I'll try to explain how the ORM works, and why it works in such way.

 

What is the ORM?

ORM is the Object-to-Relational Mapper. So, the main task of any system pretend to be ORM is mapping relational data to object data. Mapping usually means 'putting' and 'getting'.

So, the simplest possible ORM example is:

 

public class Item
{
public string Name {get;set;}
public string Description {get; set;}
}

public static IEnumerable<Item> TheSimplestORM()
{
using(var connection = new SqlConnection("connection here"))
using(var command = connection.CreateCommand("select name, description from Item_Table"))
{
connection.Open();
using(var reader = command.ExecuteReader())
{
while(reader.Read())
{
yield return new Item
{
Name = reader.GetString("name"),
Description = reader.GetString("description")
};
}
}
}
}

 

This code snippet make the thing that also makes any ORM, but make it in fast and understandable manner. I think the code above is the fastest way to put data from database to object, and I think the any ORM can't do the job faster because finally any ORM in .NET produces code like snippet above. The reasonable question is 'why the ORM so complex and sometimes so slow?'. The answer is 'Because ORM creators is too smart' is partially incorrect :) Because ORM provide may other useful features (that also slow down the overall performance). The other question is 'Do I  need these cool features?' and 'How to turn these stuff off'.

I'm going to devote one of the next posts to ORM performance. But there are many things you need to know before.

Some boring things about data.

As we say above, there are two kind of data ORM works with. These are relational data and object data.

What is the relational data? Of course, this is the data stored in database. But more precise looking give us different opinion. The relational data may be stored in relational database, but the database itself does not make any data relational.

Relational data have some properties that are important for understand how a ORM works, and why it works in such way.

Relational data has specific structure. It consists of set of elements, each element consists of set of sub-elements bla-bla. The best analogue is the table. Each table consists of rows and columns. Each row has the same set of columns (it is important thing, but quite obvious). The cross of row and column is the cell, and cell is data container.

What we can store in the cell? We can store almost all things, except other rows (yes I know a bit about advanced features of some RDBMS leaders). We can store a complex data structures in cell, like an XML files, serialized objects etc., but cell data still being a value, and we can replace cell value with the copy of data and nothing changes.

What is the object data? Object data is data contains in instances of .NET objects. The data contains in fields and accessible via different ways. The most important thing we need to know that instance can hold references to other instances as well as values (instances of value types).

At this moment this information may looks like non-useful brain work, but further it become very important :)

The ways to go ahead.

The code snippet above is pretty in their simpleness, and it can be used in different programs. You'll get collection of instances filled with data and now you can read the database data in more convenient manner then operating with raw data reader. Now I'm near the end of this post, but before I finish, I want to lists some features (some of it are even advantages) provided by ORM:

  1. Starts from the top of our snippet. The first thing provided by many ORM is generating classes by database schema. Strictly, this feature has a weak relation to ORM, but since many ORM requires persistent objects to be inherited from specified classes, implements specified interfaces or be marked with different attributes, this feature may be very useful in decreasing amount of hand-labor.
  2. Go to two lines below. Almost every ORM provides generic interface to persistence storage. So you don't need to strain a brain to invent many names for methods operates with different types of instance. Usually few methods with generic parameters are provided.
  3. ORM provides simple implicit internal management of ADO.NET primitives, like connections, commands, etc. This feature is extremely useful if you need to read/write data using different commands. Also nice ORM provides simple but strong transaction management. Usually ORM hides operations with connections, commands etc., but transaction management is exposed outside ORM.
  4. ORM usually provides way to operate with SQL instruction in more convenient manner. There are few ways to do that: provide special language to build SQL commands in term of persistent entities contract, auto-generate command from table schema and class contract, etc. The implementation may be very complex, like LINQ to SQL.
  5. ORM automates instances creation, filling instances with data and returning it. Nice ORM allows to greatly customize this aspect, and you may persist instances which contract differs from table schema in names, types and counts.

Also there are few aspects not presented in our snippet, but also very important:

  1. Maintains instance identity. Instance identity guarantee that only one instance exists for single table row. We discuss instance identity in the next post.
  2. Support object saving and deleting as well as collection saving.
  3. Persists object with references. 'Object with references' is instance of persistent class with reference to another instance of persistent class (or the same class, or even with reference to self).
  4. Persist object hierarchies. Instance may has reference to collection of another instances, and it must be loaded with object, saved with object and deleted with object.
  5. Optionally support attaching: saving instances created and changed outside the ORM boundaries.
  6. May be something else

So, thanks for attention. In next post we discuss instance identifiers, identity mapping and other buzzwords from ORM word.