[0] https://learn.microsoft.com/en-us/dotnet/csharp/programming-...
[0] https://learn.microsoft.com/en-us/dotnet/csharp/programming-...
FROM foo
WHERE baz = quux
SELECT bar
and even (the equivalent linq wont compile because ‘baz’ isn’t there anymore when the ‘where’ runs) FROM foo
SELECT bar
WHERE baz = quux
However, SQL predates smart code completion being an expected language feature, so they went for the feature “looks like normal American English” (“from the kitchen, can you get me the scales?” is less common than “can you get me the scales from the kitchen?” or “can you get me the scales? They’re in the kitchen”) instead of “make a grammar where smart code completion works well”.However if you write FROM table SELECT x, the IDE can first provide intellisense for table names while you write your FROM clause. Then it can provide intellisense for the SELECT clause based on columns in the tables/views/etc you listed in your FROM. So it was basically done for better UX.
Eg
Mylist.select(x => …) can determine the type of x, because it has the type of mylist —> List<T>
Select(x => …).from(mylist) and you simply can’t determine x, because C# type analysis can’t go backwards.
So I think it’s less a UX question and more of an absolute requirement for the API to work at all. The alternative would be a SelectFrom(x => …, mylist) function so it can be submitted in one shot, essentially what SQL is doing, but that’s disgusting — who doesn’t love function chaining?
select x => ... from mylist;
into mylist.SelectMany(x => ...);
is straightforward: C# compiler is not expected to be single-pass, it has an AST to operate upon. You'll have a LinqSelectNode with Projection (a lambda expression), Filter, and Source fields which you replace with a new ExtensionMethodCall{ Lhs = origNode.Source, MethodName = "SelectMany", Args = new []Node{ origNode.Projection }), easy.The workarounds of writing it out of order or as a SELECT first are fine... I'd almost like to see a mode the interactive client sets that just rejects any UPDATE without a WHERE, and you'd have to do WHERE 1 or similar to get an "UPDATE everything."
/* use your PPE */
BEGIN;
/* make the change */
UPDATE foo SET bar = ‘baz’;
/* sanity check */
SELECT * FROM foo WHERE bar != ‘baz’;
/* oops, let’s pretend this never happened */
ROLLBACK;And if you screw up, well that's what ROLLBACK is for.