Использование SqlQuery для получения IQueryable
Есть ли что-то, что может вернуть IQueryable
для динамического SQL-запроса в Entity Framework 6?
Это то, что я сейчас использую, но он тянет все записи (как и ожидалось).
DbContext.Database.SqlQuery<T>("SELECT * FROM dbo.SomeDynamicView")
Проблема в том, что SqlQuery
возвращает DbRawSqlQuery
, который равен IEnumerable
.
dbo.SomeDynamicView
- это представление базы данных, созданное во время выполнения.
Ответы
Ответ 1
Нет, вы не можете получить IQueryable
из SqlQuery
* потому что то, что IQueryable
выполняет, строит строку SQL динамически на основе того, что выбирает и где фильтрует вас введите. Поскольку в SqlQuery
вы предоставляете строку, Entity Framework не может сгенерировать эту динамическую строку.
Ваши параметры либо динамически строят строку, в которой ваш я должен перейти к SqlQuery
, и использовать ее как IEnumerable
вместо IQueryable
или использовать DbSet
в вашем DbContext
и делать больше "нормальный" способ предоставления объектной структуры для вас.
* Вы технически можете, вызвав AsQueryable() в результате, но это просто IEnumerable, притворяющийся IQueryable, он не дает вам каких-либо преимуществ использования "Реального" IQueryable, например, только для получения необходимых строк с сервера.
Ответ 2
Я знаю, что этот вопрос касается EF6, но в случае, если кто-то еще наткнется на этот вопрос, но интересуется EFCore, на самом деле это возможно.
Самый простой пример:
var user = new SqlParameter("user", "johndoe");
var blogs = context.Blogs
.FromSqlRaw("EXECUTE dbo.GetMostPopularBlogsForUser @user", user)
.ToList();
Параметры:
var user = new SqlParameter("user", "johndoe");
var blogs = context.Blogs
.FromSqlRaw("EXECUTE dbo.GetMostPopularBlogs @[email protected]", user)
.ToList();
Более сложный пример (это более конкретно то, о чем спрашивает этот вопрос):
var searchTerm = ".NET";
var blogs = context.Blogs
.FromSqlInterpolated($"SELECT * FROM dbo.SearchBlogs({searchTerm})")
.Where(b => b.Rating > 3)
.OrderByDescending(b => b.Rating)
.ToList();
Результирующий запрос для более сложного примера:
SELECT [b].[Id], [b].[Name], [b].[Rating]
FROM (
SELECT * FROM dbo.SearchBlogs(@p0)
) AS b
WHERE b."Rating" > 3
ORDER BY b."Rating" DESC
Несколько замечаний об этом методе:
- Вы фактически должны сделать
SELECT *
, чтобы убедиться, что все столбцы возвращены из таблицы.
- Объединения для извлечения дополнительных данных не работают, но
Include
работает в обычных запросах SQL (не обязательно хранимых вызовах процедур/функций).
- Часто ваш сырой Sql будет помещен в подзапрос. Поэтому убедитесь, что он действителен для таких вещей (то есть точки с запятой, порядок байтов, подсказки и т.д. Могут вызвать проблемы).
Ответ 3
Да Вы можете сделать следующее:
DbContext.Database.SqlQuery("SELECT * FROM dbo.SomeDynamicView").AsQueryable<T>()