Roadmap › Entity Framework (EF6 & EF Core) › Module: Querying
Lessons in this course (15)

9. Raw SQL, stored procedures and bulk operations

Intermediate★ Must knowLesson 9 of 15
csharp
// Raw SQL returning entities — interpolation is parameterised (safe)
var big = await db.Orders.FromSql($"SELECT * FROM Orders WHERE Total > {minTotal}").Where(o => o.Status == "Open").ToListAsync();

// Unmapped types (EF Core 8)
var rows = await db.Database.SqlQuery<SalesRow>($"EXEC dbo.usp_SalesByMonth @Year = {year}").ToListAsync();

// Non-query
await db.Database.ExecuteSqlAsync($"UPDATE Products SET Price = Price * {factor} WHERE CategoryId = {cat}");

// Set-based bulk update/delete without loading entities (EF Core 7)
await db.Orders.Where(o => o.CreatedAt < cutoff && o.Status == "Draft").ExecuteDeleteAsync(ct);
await db.Products.Where(p => p.CategoryId == 3)
    .ExecuteUpdateAsync(s => s.SetProperty(p => p.Price, p => p.Price * 1.1m), ct);

FromSqlRaw/ExecuteSqlRaw take a string + parameters — never concatenate user input into them. ExecuteUpdate/Delete bypass the change tracker (tracked entities become stale) and run immediately.