Eric said:
I've heard a lot of good things about LLBLGen Pro, and it's possibly a
better option than nHibernate if you want a well supported advanced
tool.
well, thank you!
But I'm not convinced that these tools are as good as the theory would
indicate. In my opinion the more advanced your DB schema is, and the
more tables and databases you have, the more difficult it will be to
make ORM work efficiently. And after a huge number of manhours to
develop the maps and tune everything you'll find yourself totally
beholden to the person who set all this up for you. If he leaves your
company you will be in for some pain.
Depends on the O/R mapper you use I guess. If the O/R mapper is up to
its task, the mappings should be pretty transparent and easy to follow.
What people often forget is that an o/r mapper isn't a toolkit which
is supporting a true Table + SQL oriented approach, after all the core
focus of an o/r mapper is on an entity / domain class mapped onto a db
construct, which can be a view or a table or set of tables / views
(inheritance).
And of course, if the mapper of choice doesn't have the ability to let
you specify different ways of expressing your filters for example, you
can run into serious performance bottlenecks.
Take for example the following: (on northwind)
let's say you want to fetch all employee entities which have filed an
order with a product P.
As there are very little employees compared to orders in this
database, a query like: (I use '*' for simplicity, a good o/r mapper of
course emits the field list)
SELECT * FROM Employees INNER JOIN Orders ON
Employees.EmployeeID = Orders.EmployeeID INNER JOIN [Order Details]
ON Orders.OrderID == [Order Details].OrderID
WHERE [Order Details].ProductID = @p
will get you a lot of duplicates for Employees. As Employee contains a
blob (Image field: Photo), you can't use DISTINCT. So all these
duplicates will be send to the o/r mapper layer and filtered there. Not
that efficient. In general this is the 1:n filter based on a join
problem. You should use a subquery instead in this case:
SELECT * FROM Employees WHERE
EmployeeID IN (SELECT EmployeeID FROM Orders WHERE OrderID IN
(Select OrderID FROM [Order Details] WHERE ProductID = @p))
This is much more efficient, as it doesn't get you the duplicates.
If the o/r mapper doesn't allow you to specify that you want a
subquery approach in this case instead of a join based approach, or if
it doesn't make this decision by itself, the developer will run into a
problem as the query will be very slow yet the # of returned entities
will likely be very low.
Watch out if you're a consultant - some companies won't allow this
type of thing to be used without prior approval.
Most of the time this is based on lack of knowledge on the subject and
also because it's not always in the best interest of the consulting
company to use tools which save a lot of time

After all, a lot of
consultants are payed by the hour. However, if the consulting company
is clever, they can manage more clients in the same period of time,
which could lead to higher profit. Luckily more and more consulting
companies understand this.
FB
--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website:
http://www.llblgen.com
My .NET blog:
http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------