Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for common table expressions (aka WITH) via special LINQ operator #26486

Open
roji opened this issue Oct 28, 2021 · 2 comments
Open

Support for common table expressions (aka WITH) via special LINQ operator #26486

roji opened this issue Oct 28, 2021 · 2 comments

Comments

@roji
Copy link
Member

roji commented Oct 28, 2021

We could have a special queryable-returning function which we'd translate into a TableExpressionBase:

from foo in EF.With(ctx.Foos.Where(....))
from bar in EF.With(ctx.Bars.Where(....))
from baz in ctx.Bazes.Where(...)
...

... becomes:

WITH foo AS (
    SELECT * FROM Foos
    WHERE ...
), bar AS (
    SELECT * FROM Bars
    WHERE ...
),
SELECT * FROM Bazes WHERE ...

Do recursive CTEs as well.

Note: CTEs are also valid with WITH ... INSERT ... INTO, WITH ... DELETE, WITH ... UPDATE.

See also #29918 (embedded IQueryables to common table expressions)

Community implementations

@smitpatel smitpatel changed the title Support for common table expressions (aka WITH) Support for common table expressions (aka WITH) using LINQ Oct 28, 2021
@smitpatel smitpatel changed the title Support for common table expressions (aka WITH) using LINQ Support for common table expressions (aka WITH) by translating LINQ query Oct 28, 2021
@ajcvickers ajcvickers added this to the Backlog milestone Nov 2, 2021
@roji
Copy link
Member Author

roji commented Dec 19, 2021

Note: all major databases support prefixing UPDATE/DELETE with CTEs (see #795 for bulk updates).

@roji
Copy link
Member Author

roji commented Aug 27, 2023

Note: all databases - except SQL Server - support embedding CTEs within arbitrary subqueries inside the query;

SELECT * FROM (WITH t AS (SELECT 1) SELECT * FROM t) AS foo;

This effectively makes CTEs an optional prefix of SelectExpression.

In addition, SQL Server (but not other databases) requires that column names be explicitly specified when they're not named within the subquery:

WITH t AS (SELECT 1 AS q) SELECT * FROM t; -- Column name bubbles out of the subquery
WITH t (q) AS (SELECT 1) SELECT * FROM t; -- Column explicitly specified as part of the CTE syntax
WITH t AS (SELECT 1) SELECT * FROM t; -- Fails in SQL Server, works elsewhere (with unknown column name)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants