LINQ to SQL Converter
Paste a LINQ query in method or query syntax and get equivalent SQL Server or PostgreSQL output, with unsupported constructs listed explicitly rather than guessed.
What this tool does
Paste a C# LINQ query — method syntax (customers.Where(...).Select(...)) or query syntax (from c in customers where ... select ...) — and get an equivalent SQL statement. Everything runs in-memory in your Blazor session using a hand-written tokenizer and recursive-descent parser; nothing is sent to an external API, and no Roslyn/compiler dependency is involved.
A field note: the LINQ queries that cause real trouble are rarely the ones that fail to compile — they're the ones that compile fine, run fine against an in-memory test double, and then throw at runtime against a real database because EF Core's SQL translator can't turn a particular expression into SQL. Seeing the SQL a query shape should produce, before it's wired up to a live DbContext, is a cheap way to catch the translation gap early — especially for the "this LINQ looks fine" queries that hide a nested navigation property or a custom method call three lines deep. If you're debugging exactly this kind of EF Core/LINQ translation surprise, see How LINQ Translates to SQL — and Where EF Core Will Surprise You. And once you know the SQL shape you need, the SQL Table to C# Entity Generator and the EF Migration Explainer cover the rest of the schema-to-code path.
Scope — what's actually supported
This is a rule-based translator for the common LINQ shapes, not a general-purpose query compiler (that's what EF Core's own provider does, with years of engineering behind it). Supported: Where, Select (including anonymous-object projections), OrderBy/OrderByDescending/ThenBy/ThenByDescending, GroupBy (single key, with Count() in the grouped projection), a single Join, Take/Skip, Count/Any/First/FirstOrDefault, and string Contains/StartsWith/EndsWith against a literal string (translated to LIKE). A bare boolean member (c.IsActive, or negated !c.IsActive) in a predicate is translated to IsActive = 1 / = 0, since T-SQL and PostgreSQL don't accept a bare column as a truthy predicate the way C# does.
Anything else is not guessed — it's listed explicitly in the warning box under the output so you know exactly what to fix by hand, rather than shipping SQL that looks plausible but is wrong:
| Construct | Why it's unsupported | What to do instead |
|---|---|---|
Sum / Average / Max / Min | Aggregate translation isn't implemented in this rule-based parser | Write the aggregate SQL by hand after converting the rest of the query |
Distinct | Not implemented | Add DISTINCT to the generated SELECT yourself |
More than one Join | Only a single Join is supported per query | Convert the first join, then hand-write the rest |
Nested navigation properties (x.Address.City) | The parser resolves only single-level member access | Flatten to a top-level property, or add the join manually |
Non-literal Contains argument (c.Name.Contains(searchTerm)) | Only literal string arguments translate to LIKE | Substitute the literal value before pasting, then parameterize by hand |
| Ternary expressions | Not implemented | Rewrite as two Where clauses, or a CASE expression by hand |
| Custom method calls | Only the fixed set of LINQ methods above is recognized | Inline the method's logic as a plain LINQ expression first |
Worked example
This method-syntax query:
customers
.Where(c => c.Country == "USA" && c.IsActive)
.OrderBy(c => c.LastName)
.Select(c => new { c.FirstName, c.LastName, c.Email })
produces this SQL Server output:
SELECT [FirstName], [LastName], [Email]
FROM [customers]
WHERE ([Country] = 'USA') AND ([IsActive] = 1)
ORDER BY [LastName]
How LINQ methods map to SQL clauses
The order you chain LINQ methods in — filter, then sort, then shape — is not the order the equivalent SQL clauses appear in. Select is usually the last call in the chain but becomes the first clause in the statement:
SQL Server vs PostgreSQL
The dialect toggle only changes two things: identifier quoting ([Brackets] for SQL Server vs "double quotes" for PostgreSQL) and how row-limiting is expressed (SELECT TOP (n) for SQL Server vs a trailing LIMIT n for PostgreSQL, with OFFSET handled per dialect for Skip). Every other part of the generated SQL is identical between the two.
How to use this tool
- Pick a target dialect — SQL Server or PostgreSQL.
- Paste a LINQ query in method or query syntax.
- Click Convert (or Ctrl+Enter).
- Check the warning box — if it's non-empty, review each listed construct before trusting the SQL.
LINQ query (C#)
customers
.Where(c => c.Country == "USA" && c.IsActive)
.OrderBy(c => c.LastName)
.Select(c => new { c.FirstName, c.LastName, c.Email })Generated SQL
SQL output