Share via


Query SQL non elaborate (EF6)

Entity Framework consente di eseguire query usando LINQ con le classi di entità. In alcuni casi, tuttavia, potrebbe essere necessario eseguire query usando SQL non elaborato direttamente sul database. Sono incluse le stored procedure chiamate, che possono essere utili per i modelli Code First che attualmente non supportano il mapping alle stored procedure. Le tecniche illustrate in questo argomento si applicano in modo analogo ai modelli creati con Code First ed EF Designer.

Scrittura di query SQL per le entità

Il metodo SqlQuery in DbSet consente la scrittura di una query SQL non elaborata che restituirà istanze di entità. Gli oggetti restituiti verranno rilevati dal contesto esattamente come se fossero restituiti da una query LINQ. Ad esempio:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs.SqlQuery("SELECT * FROM dbo.Blogs").ToList();
}

Si noti che, proprio come per le query LINQ, la query non viene eseguita fino a quando i risultati non vengono enumerati. Nell'esempio precedente questa operazione viene eseguita con la chiamata a ToList.

Prestare attenzione ogni volta che vengono scritte query SQL non elaborate per due motivi. Prima di tutto, la query deve essere scritta per garantire che restituisca solo entità realmente del tipo richiesto. Ad esempio, quando si usano funzionalità come l'ereditarietà, è facile scrivere una query che creerà entità con un tipo CLR errato.

In secondo luogo, alcuni tipi di query SQL non elaborate espongono potenziali rischi per la sicurezza, in particolare per gli attacchi SQL injection. Assicurarsi di usare i parametri nella query nel modo corretto per proteggersi da tali attacchi.

Caricamento di entità da stored procedure

È possibile usare DbSet.SqlQuery per caricare le entità dai risultati di una stored procedure. Ad esempio, il codice seguente chiama dbo. Procedura GetBlogs nel database:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs.SqlQuery("dbo.GetBlogs").ToList();
}

È anche possibile passare parametri a una stored procedure usando la sintassi seguente:

using (var context = new BloggingContext())
{
    var blogId = 1;

    var blogs = context.Blogs.SqlQuery("dbo.GetBlogById @p0", blogId).Single();
}

Scrittura di query SQL per tipi non di entità

È possibile creare una query SQL che restituisce istanze di qualsiasi tipo, inclusi i tipi primitivi, usando il metodo SqlQuery nella classe Database. Ad esempio:

using (var context = new BloggingContext())
{
    var blogNames = context.Database.SqlQuery<string>(
                       "SELECT Name FROM dbo.Blogs").ToList();
}

I risultati restituiti da SqlQuery nel database non verranno mai rilevati dal contesto anche se gli oggetti sono istanze di un tipo di entità.

Invio di comandi non elaborati al database

I comandi non di query possono essere inviati al database usando il metodo ExecuteSqlCommand nel database. Ad esempio:

using (var context = new BloggingContext())
{
    context.Database.ExecuteSqlCommand(
        "UPDATE dbo.Blogs SET Name = 'Another Name' WHERE BlogId = 1");
}

Si noti che tutte le modifiche apportate ai dati nel database tramite ExecuteSqlCommand sono opache per il contesto fino a quando le entità non vengono caricate o ricaricate dal database.

Parametri di output

Se vengono usati parametri di output, i relativi valori non saranno disponibili fino a quando i risultati non saranno stati letti completamente. Ciò è dovuto al comportamento sottostante di DbDataReader, vedere Recupero di dati tramite un DataReader per altri dettagli.