0Pricing
C# Academy · Lezione

SQL nativo, stored procedure e interpolazione

Esegua SQL nativo in modo sicuro con FromSqlRaw, FromSqlInterpolated e stored procedure, evitando le injection.

SQL nativo, stored procedure e interpolazione è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.

Quando usare SQL raw in EF Core

La maggior parte delle query funziona bene con LINQ, ma alcuni scenari richiedono SQL raw: analisi complesse, funzioni specifiche del fornitore, stored procedure o query critiche per le prestazioni che LINQ traduce in modo inefficiente.

EF Core offre modalità sicure per utilizzare SQL raw senza compromettere la sicurezza.

FromSqlRaw: query parametrizzate sicure

FromSqlRaw esegue SQL raw e riconverte i risultati in entità. Utilizzi sempre segnaposto {0} — mai la concatenazione di stringhe — per prevenire l'SQL injection.

// SAFE: parameterized
var products = await _db.Products
    .FromSqlRaw("SELECT * FROM Products WHERE Price > {0}", 100m)
    .ToListAsync();

// DANGEROUS: never do this
// FromSqlRaw("SELECT * FROM Products WHERE Price > " + price)

FromSqlInterpolated: sicurezza delle stringhe interpolate

FromSqlInterpolated accetta una stringa interpolata C#. EF Core converte automaticamente i valori interpolati in parametri SQL: una soluzione sicura e leggibile.

decimal minPrice = 100m;
string category = "Electronics";

var products = await _db.Products
    .FromSqlInterpolated(
        $"SELECT * FROM Products WHERE Price > {minPrice} AND Category = {category}")
    .OrderBy(p => p.Name)
    .ToListAsync();
// Values become @p0, @p1 parameters automatically

Comporre query LINQ dopo FromSql

È possibile concatenare operatori LINQ dopo FromSql. EF Core racchiude il vostro SQL raw in una sottoquery e applica LINQ al di sopra, una soluzione utile per aggiungere filtri o la paginazione.

decimal min = 50m;
var page = await _db.Products
    .FromSqlInterpolated($"SELECT * FROM Products WHERE Price > {min}")
    .Where(p => p.IsActive)        // additional LINQ filter
    .OrderBy(p => p.Price)
    .Skip(0).Take(20)              // pagination
    .ToListAsync();
// Generates: SELECT ... FROM (raw SQL) AS p WHERE ...

Eseguire stored procedure

Richiami le stored procedure che restituiscono righe di entità tramite FromSqlRaw. Per le procedure che non restituiscono righe (ad esempio INSERT/UPDATE), utilizzi ExecuteSqlRawAsync.

// Stored proc returning Products
var products = await _db.Products
    .FromSqlRaw("EXEC GetProductsByCategory {0}", "Books")
    .ToListAsync();

// Stored proc with no return rows
await _db.Database.ExecuteSqlRawAsync(
    "EXEC ArchiveOldOrders {0}",
    DateTime.UtcNow.AddYears(-1));

ExecuteSqlInterpolated per il DML

ExecuteSqlInterpolated esegue istruzioni DML (INSERT, UPDATE, DELETE) con la sicurezza delle stringhe interpolate. Restituisce il numero di righe interessate.

int days = 30;
int affected = await _db.Database.ExecuteSqlInterpolatedAsync(
    $"UPDATE Orders SET Status = 'Expired' WHERE PlacedAt < {DateTime.UtcNow.AddDays(-days)}");

Console.WriteLine($"{affected} orders expired");

Eseguire query su tipi non appartenenti a entità

Utilizzi SqlQuery<T> (.NET 7+) per eseguire query su tipi scalari o DTO arbitrari che non sono entità EF Core. Non è necessario alcun DbSet.

// Query a DTO directly — no entity needed
var stats = await _db.Database
    .SqlQuery<ProductStats>(
        $"SELECT Category, COUNT(*) AS Count, AVG(Price) AS AvgPrice FROM Products GROUP BY Category")
    .ToListAsync();

public record ProductStats(string Category, int Count, decimal AvgPrice);

Tipi di entità senza chiave per le viste

Esegua il mapping di una vista del database o del risultato di una query raw a un tipo di entità senza chiave usando HasNoKey() e ToView(). Potrà eseguire query come su un DbSet senza aver bisogno di una chiave primaria.

public class ProductSalesSummary
{
    public string Category { get; set; } = "";
    public int TotalSold { get; set; }
    public decimal Revenue { get; set; }
}

// In OnModelCreating:
modelBuilder.Entity<ProductSalesSummary>()
    .HasNoKey()
    .ToView("vw_ProductSalesSummary");

// Query:
var summary = await _db.Set<ProductSalesSummary>().ToListAsync();

Evitare le insidie dell'SQL injection

La regola d'oro: non concatenare mai l'input dell'utente nelle stringhe SQL. Utilizzi sempre query parametrizzate tramite i segnaposto di FromSqlRaw, FromSqlInterpolated o LINQ di EF Core.

// SAFE
var name = userInput;
var result = await _db.Products
    .FromSqlInterpolated($"SELECT * FROM Products WHERE Name = {name}")
    .ToListAsync();

// INJECTION RISK (never do this)
// FromSqlRaw("SELECT * FROM Products WHERE Name = '" + name + "'");

Parametri di output con fallback ad ADO.NET

EF Core non supporta nativamente i parametri di output delle stored procedure. In questi casi, ricorra ad ADO.NET usando _db.Database.GetDbConnection().

await _db.Database.OpenConnectionAsync();
var conn = _db.Database.GetDbConnection();
using var cmd = conn.CreateCommand();
cmd.CommandText = "EXEC GetOrderCount @CustomerId, @Count OUTPUT";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@CustomerId", 5));
var outParam = new SqlParameter("@Count", SqlDbType.Int) { Direction = ParameterDirection.Output };
cmd.Parameters.Add(outParam);
await cmd.ExecuteNonQueryAsync();
int count = (int)outParam.Value;

Nella pratica: fallback per la ricerca full-text

LINQ non consente di esprimere i predicati di ricerca full-text specifici del database. Utilizzi FromSqlInterpolated per sfruttare le funzionalità native FREETEXT o tsvector.

string query = "keyboard mechanical";
var results = await _db.Products
    .FromSqlInterpolated(
        $"SELECT * FROM Products WHERE FREETEXT(Name, {query})")
    .AsNoTracking()
    .Take(20)
    .ToListAsync();

Verifica rapida

Perché FromSqlInterpolated è più sicuro della concatenazione di stringhe per le query parametrizzate?

Riepilogo: SQL raw in EF Core

Punti chiave:

  • FromSqlRaw: utilizzi segnaposto {0}; non concateni mai l'input dell'utente
  • FromSqlInterpolated: stringhe interpolate sicure → parametri ADO.NET
  • Concateni operatori LINQ dopo FromSql per aggiungere filtri, ordinamento e paginazione
  • ExecuteSqlInterpolatedAsync: esecuzione sicura del DML
  • SqlQuery<T>: esecuzione di query su DTO non appartenenti a entità (.NET 7+)
  • Utilizzi direttamente ADO.NET per i parametri di output o le stored procedure complesse

Domande Frequenti

La lezione «SQL nativo, stored procedure e interpolazione» è gratuita?

Sì — il testo completo di «SQL nativo, stored procedure e interpolazione» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.

Cosa imparerò in «SQL nativo, stored procedure e interpolazione»?

Esegua SQL nativo in modo sicuro con FromSqlRaw, FromSqlInterpolated e stored procedure, evitando le injection. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C# Academy?

Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «SQL nativo, stored procedure e interpolazione»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C# Academy?

Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Caricamento eager, lazy ed esplicito
  2. SQL nativo, stored procedure e interpolazione
  3. Query compilate e prestazioni
  4. Filtri globali per le query ed entità possedute
← Torna a C# Academy