I wanted to share with you some experience about the ORM I used for my projects in Delphi. So many of you were questioned about the choice of the ORM framework to use. There are some old ones and new to choose from (the list is incomplete and you are welcome to complete it):
- DORM – very promising and looks solid Delphi ORM by Daniele Teti;
- Marshmallow – open source ORM for Delphi for fans of Spring4D;
- Bold – some legacy ORM solution which is not supported any more as far as I know;
- tiOPF – Object persistence framework for Delphi. Files on sf.net are dated with 2008;
- G-framework – but I can’t find any useful website or place where it is hosted;
- mORMot framework – very specific ORM framework which is the most hard to understand. It was probably developed for own internal project but then later published. If you look at the code you find a bit weird formatting, but that’s matter of taste. The library is huge. The library is well documented and certain parts are unit tested. Most of the routines are performance bargains (they are really optimized well)! This library can be a really good choice for persistence, especially if you are planning to extend your application to n-tier architecture;
- TMS Aurelius – a commercial ORM solution. Basing on my personal experience with TMS VCL components I will never ever use it in my production systems (actually our team trying to get rid of these components in the project), because TMS and quality code is two different and incompatible things (I should make note there – that’s my personal opinion which you should never take into account and instead make your own test-drive of the library, inspect the code and make your decision). Who knows, maybe this product is much better and more of quality then VCL part;
- DevART EntityDAC – free/commercial ORM framework. Additionally to the ORM mapping the framework also supports the LINQ (yes, real LINQ-like) syntax for querying the data.
Currently I use the EntityDAC framework. There are two options to go with this product:
- Express edition – free version where most of the core things woks, but there is no visual designer for model generation from the database as well no dataset components for entities;
- Standard or Professional – commercial version which adds some very handful features and provides the good visual tool for modeling.
The use of the EntityDAC is quite simple from the beginning. The Entity Developer (for modeling) tool is amazing – all is as you expect:
- Drag and drop tables from the database to the diagram;
- Automatically resolves all foreign keys and creates the associations;
- You can define the rules of field and table naming in generated classes;
- You can adjust defaults, add constraints and associations manually.
The ORM part works almost the same way as Marshmallow or Aurelius. The nice thing which EntityDAC adds is their LINQ feature. That allows us to completely remove the “stringly-typed” stuff from our source code – so that our database fields and tables are validated at compile time! The cool thing is that you can build the where statement using standard flow operators to either include or exclude the filter:
var LExp: TExpression; LUser: IUserExpression; U: TUser; begin ... LExp := LUser.UserName = 'admin'; if BoxAutologin.Checked then LExp := LExp and LUser.Autologin; for U in Context.GetEntities<TUser>(From(Context.User).Where(LExp)) do ... end;
You can use all of the operators to build the conditions. If you ask how does that work then answer is simple – operator overloading done right! For more LINQ examples just go to their documentation.
But never try to completely replace the SQL with LINQ – on some cases it’s much more efficient to use the raw SQL instead of the LINQ to perform certain tasks – so choose the right tool for the right job!
Ok, so far so good. But what’s missing you ask?
For that I will just summarize the pluses and minuses from my point of view.
- Free version available;
- Very good database tool;
- Good documentation;
- Very good code quality (I had it with source) – they really use the design patterns and do good stuff in background!
- Amazing LINQ language support in Delphi syntax;
- Takes a bit to understand how to build more complex LINQ queries;
- No IN statement support (however I do not know if any of ORMs has support for that);
- Support team is kind of slow. Yes, it has bugs and I did report them, they confirmed them and replied “we will fix it asap…”. But the fixes are coming once in a half a year at best. Some of the issues are not fixed already for two releases since I reported them. I even am forced to fix their issues myself using the source code – that’s the only savior in this case until the support team starts working as good as DevExpress one 😀
And one more missing thing in this library is the following: the generated ORM classes are generated without abstraction interfaces. So when you access entities and their fields you access objects not interfaces. That will be really amazing if that will be added some day, because then there will be a nice possibility to mock the entity access at least in certain places.