I’m far from a C# expert, I just happen to write some at work but that’s not my predilection language so you probably know better than me but, implementation appart, as a querying language, it feels pretty good.
Also, I understood that it was translated to IEnumerable queries, so, wouldn’t EF optimize the query ?
EF translate will translate your LINQ into SQL.
I'm speaking about LINQ that you may write anywhere, not on a DB call in particular, there EF is not the right tool, there may be some things thats may make LINQ faster, but it's nowhere as good (it cant do much as most of the queries are little isolated queries) as a DB engine.
Not being familiar with LINQ, does it solve SQL's composability problems?
I love SQL for what it can do, but I am constantly annoyed at how inconsistent it is and how terrible it is for generating queries via software. It feels ripe for a replacement that is semantically similar but syntactically different.
I'm familiar with what it does (conceptually), but what I want to know is: Is it composable? Eg if I have a query and I want to add an additional filter to it, or I have a select that I want to turn into an update, is it straightforward? SQL syntax tends to make this kind of query generation difficult (though obviously not impossible).
The query is composable, not the object it process (it's still a C# object).
A LINQ method return an IEnemurable(this interface allow simply to read the object one per one.)
You can add filters, groups, order, as much as you want, because each will return an IEnumerable (some methods return a child interface, like Order, which return an IOrderedEnumerable).
Then, you consume this this enumerable, most of the time with a foreach (procedural, or LINQ style, and will consume the enumerable), where you can update the values.
In the end, it's still C#: you can add side effects, where you want, even in the select, even if you shouldn't.
Most of the times, "when it tends to make this kind of query difficult" you can just consume your query with a foreach, and do the rest with the procedural style.
LINQ has multiples issues compared to what I want to do.
It's slow (at leat 1000x slower than a for loop)
There is no query optimizer by default, and even less a runtime query optimiser.
It's directly translated to procedural code, it doesn't get compiled and translated like a query engine will do in an SQL DB.