Hacker News new | ask | show | jobs
by kyberias 1239 days ago
This is why Language Integrated Query (LINQ) is so powerful in .NET. You never need to learn any ORM specific query language or syntax since you've probably learned to use LINQ with objects already and then you just continue to use it with a database.
3 comments

True in the sense that you do not need to learn anything extra to build queries using an ORM. But it is not the complete picture: whenever you use an ORM, you should really know how the ORM works and what it does. For example, even if you use LINQ, you have to realize that the expressions you use in the C# code cannot always be translated to SQL. So, you need to know the ORM and its limitations to be aware of what is possible and what is not. An ORM cannot magically translate the code behind a derived property into SQL.

ORM should definitely not be regarded as a technology that allows you to use SQL and RDBMS without knowing those technologies. ORM should be regarded as a technology that can make you much more efficient when using SQL and RDBMS, when you already have good knowledge on SQL and RDBMS. An ORM should help you with all the 'routine' SQL stuff. And a good ORM will support you using straight SQL whenever you want to do something that the ORM does not support well.

I love LINQ, but I've noticed that there are people that think they know LINQ, and then think they can use an ORM because of that. And in the end, they do not really know LINQ, they do not really know how an ORM works, and their code generates SQL queries that have really poor performance. And then the obvious conclusion is that ORMs are bad. Well.... no, they are not, they are very powerful tools, but it requires knowledge to use them well.

Yes, and LINQPad lets you write very powerful ad-hoc queries with results that are significantly easier to navigate. It's much better than using SQL management studio to view your database.

FWIW: I shipped a C# product with a very simple SQLite database. When the application started LINQtoSQL wasn't available (we used Mono,) so we just wrote our own queries.

Best decision ever. We didn't need to do the various futzing and learning curve that comes with learning an ORM. Granted, it only worked because we had a handful of tables, very basic CRUD, and infrequent schema changes.

Still, if you fall into the "I must use an ORM/hand SQL" camps, you're probably limiting yourself due to your biases.

LINQ is nice, but EF Core has some significant limitations and forces you down some pretty sub optimal design paths.
Please elaborate on the limitations and paths! I'm doing technology selection research and EF Core is currently on the table, would love to hear what you encountered.
One of the most significant for our use case is that composite primary keys do not work with inheritance, which makes it impossible to setup constrained polymorphic relationships.
In general, if you use your database domain (classes) in your business logic, you will have pitfalls when working with your database. This either leads to the N+1 problem (when you use lazy loading), or data structures where a relationship will be null when you try to traverse it.

(Basically, if you use lazy loading, your code will be slow and may require major refactors late in the project life. If you use aggressive loading, your code may have bugs when expected relationships aren't populated.)

I should point out that this isn't purely an EF core limitation! The "correct" approach is to always copy objects from database domain (classes) to business logic domain (classes); but this is often more effort than it's worth.

I'd be really interested to know some recommended methods of realizing having separate db and domain classes. I'm actually in the early phases of a project where I have been using the Memento pattern to save and restore domain entities. I'm about ready to rip it out and switch back to persisting the domain classes directly in the db because it's so tedious. (using EF Core 7 and C#)
Would love to hear this too. I’ve yet to have a problem with EF Core.