efcore icon indicating copy to clipboard operation
efcore copied to clipboard

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

Open roji opened this issue 4 years ago • 2 comments

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

roji avatar Oct 28 '21 22:10 roji

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

roji avatar Dec 19 '21 19:12 roji

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)

roji avatar Aug 27 '23 18:08 roji

@ajcvickers and @roji I hope CTEs and window functions #12747 will be added to 10.0 milestone for boost performance of advanced queries with grouping and aggregation.

mojtabakaviani avatar Nov 23 '24 19:11 mojtabakaviani

+1 this would be great to see and would benefit us across a number of projects

Pepsi1x1 avatar Dec 06 '24 13:12 Pepsi1x1