
Entity Framework позволяет выполнять запросы используя LINQ с вашими классами сущностей (entity classes). Однако могут быть случаи когда вы хотите выполнить чистые 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
класса Database
никогда не будут отслежены контекстом, даже если экземпляры являются типа сущности.
Отправка простых команд базе данных
Простые команды могут быть отправлены базе данных используя метод ExecuteSqlCommand
класса Database
. Например:
using (var context = new BloggingContext()) { context.Database.SqlCommand( "UPDATE dbo.Blogs SET Name = 'Another Name' WHERE BlogId = 1"); }
Обратите внимание на то, что любые изменения сделанные в базе данных испозуя метод ExecuteSqlCommand являются непрозрачными для контекста до тех пор пока сущности не будут загружены или перезагружены из базы данных.
Источник тут.