View Generated SQL from LINQ Queries

See exactly what SQL queries Entity Framework Core generates from your LINQ expressions

Understanding Generated SQL

EF Core translates LINQ queries into SQL. Understanding the generated SQL helps you: identify performance issues, verify index usage, debug unexpected behavior, and optimize complex queries.

LINQ Query 1

LINQ Expression
DemoProducts.Where(p => p.Price > 100).Take(10)

Generated SQL
DECLARE @__p_0 int = 10;

SELECT TOP(@__p_0) [d].[Id], [d].[Category], [d].[CreatedDate], [d].[Description], [d].[IsActive], [d].[Name], [d].[Price], [d].[Rating], [d].[ReviewCount], [d].[SKU], [d].[StockQuantity]
FROM [DemoProducts] AS [d]
WHERE [d].[Price] > 100.0
Key Points:
  • Filtering applied at database level
  • Row limiting using SQL Server TOP clause

LINQ Query 2

LINQ Expression
DemoProducts.GroupBy(p => p.Category).Select(g => new { Category = g.Key, Count = g.Count() })

Generated SQL
SELECT [d].[Category], COUNT(*) AS [Count]
FROM [DemoProducts] AS [d]
GROUP BY [d].[Category]
Key Points:
  • Aggregation performed at database level

LINQ Query 3

LINQ Expression
DemoProducts.Where(p => p.IsActive).OrderBy(p => p.Rating).ThenBy(p => p.Price).Take(20)

Generated SQL
DECLARE @__p_0 int = 20;

SELECT TOP(@__p_0) [d].[Id], [d].[Category], [d].[CreatedDate], [d].[Description], [d].[IsActive], [d].[Name], [d].[Price], [d].[Rating], [d].[ReviewCount], [d].[SKU], [d].[StockQuantity]
FROM [DemoProducts] AS [d]
WHERE [d].[IsActive] = CAST(1 AS bit)
ORDER BY [d].[Rating], [d].[Price]
Key Points:
  • Filtering applied at database level
  • Sorting performed by SQL Server
  • Row limiting using SQL Server TOP clause

How to View SQL in Your Own Code

Method 1: ToQueryString()
var query = _context.Products
    .Where(p => p.Price > 100)
    .OrderBy(p => p.Name);

// Get the SQL before executing
string sql = query.ToQueryString();
Console.WriteLine(sql);

// Then execute
var results = await query.ToListAsync();
Method 2: Enable Logging
// In Program.cs
builder.Services.AddDbContext<DemoDbContext>(options =>
{
    options.UseSqlServer(connectionString);
    
    // Log SQL to console
    options.LogTo(Console.WriteLine, 
        LogLevel.Information);
        
    // Or use this filter
    builder.Logging.AddFilter(
        "Microsoft.EntityFrameworkCore.Database.Command",
        LogLevel.Information);
});

Method 3: SQL Server Profiler

Use SQL Server Profiler or Extended Events to capture all queries hitting your database in real-time.

  • See actual execution plans
  • Monitor query performance
  • Identify slow queries
Method 4: MiniProfiler
# Install MiniProfiler
dotnet add package MiniProfiler.AspNetCore.Mvc
dotnet add package MiniProfiler.EntityFrameworkCore

Provides a UI overlay showing all queries, their execution time, and duplicate query detection.

Tips for Analyzing Generated SQL

✅ Good Signs
  • WHERE clauses present
  • Indexed columns used
  • TOP/FETCH for limiting results
  • Single query for related data
  • Appropriate JOINs
  • GROUP BY for aggregations
⚠️ Warning Signs
  • SELECT * (fetching all columns)
  • No WHERE clause on large tables
  • Complex nested subqueries
  • Cartesian products (missing JOIN conditions)
  • Multiple queries for same data
❌ Red Flags
  • No indexes used (table scans)
  • N+1 query pattern
  • Functions on indexed columns in WHERE
  • Client evaluation warnings
  • Fetching all data then filtering