When teams abandons an Object-Relational Mapper, ORM, because they think it doesn’t perform well or adds too much magic, then it is often due to bad usage Jimmy Bogard states in a recent presentation highlighting what he sees as correct and incorrect ways of using an ORM, including mapping and querying problems.
Jimmy, creator of AutoMapper and a Microsoft MVP, describes an ORM as a tool for getting information from a database to an application and back again, which may look like an easy problem but turns out to be quite complicated.
One mapping problem Jimmy describes is database-generated mapping code where a tool creates the code from an existing database. This may look attractive but he typically finds too many relationships and extraneous navigations that will give performance problems. Instead Jimmy uses code-first, adding mapping and relations as they are needed, even for an existing database.
In Jimmy’s experience, one of the first things developers tend to complain about when using an ORM is excessive lazy loading and Select N+1 loading, features that will make an ORM delay loading all data in a complex model, instead reading data as needed. The problem is that it may result in many calls to the database, e.g. each time reading a property or when looping over a collection. Instead Jimmy prefers to use eager fetch as much as possible, reading all the data needed in one request.
Repository is a pattern that Jimmy thinks is a bad idea. In the original DDD book repositories was intended to be an interface that looks like a collection on top of a data store but Jimmy believes the pattern has morphed into a façade pattern over an ORM that hides many ORM-specific features. This makes the repository just a dumb interface with an implementation that is just a delegation to the actual ORM. For the ORM to be used effectively these hidden features still need to be used which will make implementation details leak up into the application making repositories nothing more than fancy wrappers on top of ORM’s.
Instead of repositories Jimmy prefer to model each data request as a command or a query moving all code for dealing with a specific request into one class. Changes e.g. a new data access strategy is thus encapsulated in one specific class.
One of the final bad ideas Jimmy mentions is SQL ignorance. ORM is not a way to avoid knowing SQL, for business critical systems running on top of an ORM it’s crucial to know what SQL is being run and how it performs.