Поделиться через


Необработанные SQL-запросы (EF6)

Entity Framework позволяет запрашивать запросы с помощью LINQ с классами сущностей. Однако может возникнуть время выполнения запросов с помощью необработанного SQL непосредственно в базе данных. Это включает вызов хранимых процедур, которые могут быть полезны для моделей Code First, которые в настоящее время не поддерживают сопоставление с хранимыми процедурами. Методы, представленные в этом разделе, также применимы к моделям, созданным с помощью Code First и конструктора EF.

Написание запросов SQL для сущностей

Метод SqlQuery в DbSet позволяет записывать необработанный SQL-запрос, который вернет экземпляры сущностей. Возвращаемые объекты будут отслеживаться контекстом так же, как они были бы возвращены запросом LINQ. Например:

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

Обратите внимание, что, как и для запросов LINQ, запрос не выполняется, пока результаты не перечисляются, в приведенном выше примере это делается с вызовом ToList.

При написании необработанных запросов SQL следует учитывать два причины. Во-первых, запрос должен быть записан, чтобы он возвращал только сущности, которые действительно имеют запрошенный тип. Например, при использовании таких функций, как наследование, можно легко написать запрос, который создаст сущности, имеющие неправильный тип СРЕДЫ CLR.

Во-вторых, некоторые типы необработанных SQL-запросов предоставляют потенциальные риски безопасности, особенно при атаках на внедрение SQL. Убедитесь, что в запросе используются параметры правильно, чтобы защититься от таких атак.

Загрузка сущностей из хранимых процедур

DbSet.SqlQuery можно использовать для загрузки сущностей из результатов хранимой процедуры. Например, следующий код вызывает dbo. Процедура GetBlogs в базе данных:

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

Можно также передать параметры в хранимую процедуру с помощью следующего синтаксиса:

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

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

Написание запросов SQL для типов сущностей, не являющихся сущностями

Sql-запрос, возвращающий экземпляры любого типа, включая примитивные типы, можно создать с помощью метода SqlQuery в классе Database. Например:

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

Результаты, возвращаемые из SqlQuery в базе данных, никогда не будут отслеживаться контекстом, даже если объекты являются экземплярами типа сущности.

Отправка необработанных команд в базу данных

Команды без запросов можно отправлять в базу данных с помощью метода ExecuteSqlCommand в Базе данных. Например:

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

Обратите внимание, что любые изменения, внесенные в базу данных с помощью ExecuteSqlCommand, непрозрачны к контексту, пока сущности не загружаются или перезагружаются из базы данных.

Выходные параметры

Если используются выходные параметры, их значения не будут доступны до тех пор, пока результаты не будут прочитаны полностью. Это связано с базовым поведением DbDataReader, см . дополнительные сведения о получении данных с помощью DataReader .