Partilhar via


Consultas SQL brutas (EF6)

O Entity Framework permite que você consulte usando LINQ com suas classes de entidade. No entanto, pode haver ocasiões em que você deseja executar consultas usando SQL bruto diretamente no banco de dados. Isso inclui a chamada de procedimentos armazenados, que podem ser úteis para modelos Code First que atualmente não dão suporte ao mapeamento para procedimentos armazenados. As técnicas mostradas neste tópico se aplicam igualmente a modelos criados com o Code First e com o EF Designer.

Escrevendo consultas SQL para entidades

O método SqlQuery no DbSet permite que uma consulta SQL bruta seja gravada que retornará instâncias de entidade. Os objetos retornados serão acompanhados pelo contexto exatamente como seriam se fossem retornados por uma consulta LINQ. Por exemplo:

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

Observe que, assim como para consultas LINQ, a consulta não é executada até que os resultados sejam enumerados—no exemplo acima, isso é feito com a chamada para ToList.

Os cuidados devem ser tomados sempre que as consultas SQL brutas forem escritas por dois motivos. Primeiro, a consulta deve ser gravada para garantir que ela retorne apenas entidades que são realmente do tipo solicitado. Por exemplo, ao usar recursos como herança, é fácil escrever uma consulta que criará entidades do tipo CLR errado.

Em segundo lugar, alguns tipos de consulta SQL bruta expõem possíveis riscos de segurança, especialmente em torno de ataques de injeção de SQL. Certifique-se de usar parâmetros em sua consulta da maneira correta para se proteger contra esses ataques.

Carregando entidades de procedimentos armazenados

Você pode usar DbSet.SqlQuery para carregar entidades dos resultados de um procedimento armazenado. Por exemplo, o código a seguir chama o procedimento dbo.GetBlogs no banco de dados:

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

Você também pode passar parâmetros para um procedimento armazenado usando a seguinte sintaxe:

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

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

Escrevendo consultas SQL para tipos que não são de entidade

Uma consulta SQL que retorna instâncias de qualquer tipo, incluindo tipos primitivos, pode ser criada usando o método SqlQuery na classe Database. Por exemplo:

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

Os resultados retornados do SqlQuery no Banco de Dados nunca serão acompanhados pelo contexto, mesmo que os objetos sejam instâncias de um tipo de entidade.

Enviando comandos brutos para o banco de dados

Comandos que não consultam podem ser enviados para o banco de dados usando o método ExecuteSqlCommand no Banco de Dados. Por exemplo:

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

Observe que as alterações feitas nos dados no banco de dados usando ExecuteSqlCommand são opacas no contexto até que as entidades sejam carregadas ou recarregadas do banco de dados.

Parâmetros de saída

Se os parâmetros de saída forem usados, seus valores não estarão disponíveis até que os resultados tenham sido lidos completamente. Isso ocorre devido ao comportamento subjacente de DbDataReader, consulte Recuperar dados usando um DataReader para obter mais detalhes.