Entity Framework6の動的SQLクエリに対してIQueryable
を返すことができるものはありますか?
これは私が現在使用しているものですが、すべてのレコードをプルしています(予想どおり)。
DbContext.Database.SqlQuery<T>("SELECT * FROM dbo.SomeDynamicView")
問題は、SqlQuery
が DbRawSqlQuery
を返すことです。これはIEnumerable
です。
dbo.SomeDynamicView
は、実行時に作成されるデータベースビューです。
いいえ、IQueryable
からSqlQuery
を取得することはできません*、これは、IQueryable
が実行しているのは、入力した選択と場所に基づいてSQL文字列を動的に構築するためです。SqlQuery
では文字列を提供しているため、EntityFrameworkはその動的な文字列を生成できません。ストリング。
オプションは、自分で文字列を動的に作成してSqlQuery
に渡し、それをIEnumerable
ではなくIQueryable
として使用するか、DbSet
を使用することです。 DbContext
を実行し、エンティティフレームワークにクエリを構築させるためのより「通常の」方法を実行します。
*技術的には、結果に対して AsQueryable() を呼び出すことで可能ですが、これはIQueryableのふりをしているIEnumerableであり、「実際の」IQueryableを使用するメリットはありません。サーバーから必要な行を取得します。
私はこの質問が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 @filterByUser=@user", 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クエリでは機能します(必ずしもストアドプロシージャ/関数呼び出しである必要はありません)。