Consultas SQL sin procesar (EF6)

Entity Framework permite consultar mediante LINQ con las clases de entidad. Sin embargo, puede haber ocasiones en las que quiera ejecutar consultas mediante SQL sin procesar directamente en la base de datos. Esto incluye llamar a procedimientos almacenados, lo que puede resultar útil para los modelos de Code First que actualmente no admiten la asignación a procedimientos almacenados. Las técnicas que se muestran en este tema se aplican igualmente a los modelos creados con Code First y EF Designer.

Escritura de consultas SQL para entidades

El método SqlQuery en DbSet permite escribir una consulta SQL sin procesar que devolverá instancias de entidad. Un seguimiento de los objetos devueltos será realizado por el contexto tal y como lo serían si fueran devueltos por una consulta LINQ. Por ejemplo:

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

Tenga en cuenta que, al igual que para las consultas LINQ, la consulta no se ejecuta hasta que se enumeran los resultados; en el ejemplo anterior, esto se realiza con la llamada a ToList.

Se debe tener cuidado cada vez que las consultas SQL sin procesar se escriben por dos motivos. En primer lugar, la consulta debe escribirse para asegurarse de que solo devuelve entidades que realmente son del tipo solicitado. Por ejemplo, al usar características como la herencia, es fácil escribir una consulta que cree entidades que sean del tipo CLR incorrecto.

En segundo lugar, algunos tipos de consultas SQL sin procesar exponen posibles riesgos de seguridad, especialmente en torno a los ataques por inyección de código SQL. Asegúrese de usar parámetros en la consulta de la manera correcta de protegerse contra estos ataques.

Carga de entidades desde procedimientos almacenados

Puede usar DbSet.SqlQuery para cargar entidades a partir de los resultados de un procedimiento almacenado. Por ejemplo, el código siguiente llama a dbo. Procedimiento GetBlogs en la base de datos:

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

También puede pasar parámetros a un procedimiento almacenado mediante la sintaxis siguiente:

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

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

Escritura de consultas SQL para tipos que no son de entidad

Una consulta SQL que devuelve instancias de cualquier tipo, incluidos los tipos primitivos, se puede crear mediante el método SqlQuery en la clase Database. Por ejemplo:

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

El contexto nunca realizará el seguimiento de los resultados devueltos desde SqlQuery on Database, incluso si los objetos son instancias de un tipo de entidad.

Envío de comandos sin formato a la base de datos

Los comandos que no son de consulta se pueden enviar a la base de datos mediante el método ExecuteSqlCommand en Database. Por ejemplo:

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

Tenga en cuenta que los cambios realizados en los datos de la base de datos mediante ExecuteSqlCommand son opacos en el contexto hasta que las entidades se cargan o se vuelven a cargar desde la base de datos.

Parámetros de salida

Si se usan parámetros de salida, sus valores no estarán disponibles hasta que los resultados se hayan leído completamente. Esto se debe al comportamiento subyacente de DbDataReader, consulte Recuperación de datos mediante dataReader para obtener más detalles.