使用SqlQuery获取IQueryable

时间:2014-10-01 14:19:38

标签: entity-framework entity-framework-6

是否可以在Entity Framework 6中为动态SQL查询返回IQueryable

这就是我现在使用的,但它正在拉动所有记录(如预期的那样)。

DbContext.Database.SqlQuery<T>("SELECT * FROM dbo.SomeDynamicView")

问题是SqlQuery返回IEnumerable dbo.SomeDynamicView

{{1}}是在运行时创建的数据库视图。

2 个答案:

答案 0 :(得分:18)

不,你无法从IQueryable * 获得SqlQuery,这是因为IQueryable正在做的是基于动态构建SQL字符串选择什么以及放入哪些过滤器。因为在SqlQuery中您提供的字符串实体框架无法生成该动态字符串。

您的选项要么动态构建您自己的字符串以传递到SqlQuery并将其用作IEnumerable而不是IQueryable,或者在您的DbSet中使用DbContext {{1}}并采用更“正常”的方式让实体框架为您构建查询。


*从技术上讲,你可以通过调用AsQueryable()来获得结果,但这只是一个伪装成IQueryable的IEnumerable,它不会给你带来任何使用“真正的”IQueryable的好处仅从服务器检索所需的行。

答案 1 :(得分:0)

我知道这个问题是关于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查询中(不一定存储了proc /函数调用)起作用。
  • 通常,您的原始Sql将放入子查询中。因此,请确保它对此类情况有效(例如,分号,订单项,提示等可能会引起问题)。