【问题标题】:Using SqlQuery to get IQueryable使用 SqlQuery 获取 IQueryable
【发布时间】:2014-10-01 14:19:38
【问题描述】:

对于 Entity Framework 6 中的动态 sql 查询,是否可以返回 IQueryable

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

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

问题是SqlQuery 返回DbRawSqlQuery,即IEnumerable

dbo.SomeDynamicView 是在运行时创建的数据库视图。

【问题讨论】:

  • 动态sql查询是什么意思?
  • 动态 SQL 查询.. SELECT * FROM SomeTable1 或 SELECT * FROM SomeTable2。

标签: entity-framework entity-framework-6


【解决方案1】:

不,您无法从 SqlQuery* 获得 IQueryable,这是因为 IQueryable 所做的是根据您的选择和过滤位置动态构建 SQL 字符串放入。因为在SqlQuery 中,您提供的字符串实体框架无法生成该动态字符串。

您的选择是动态构建您自己的字符串以传递给SqlQuery 并将其用作IEnumerable 而不是IQueryable 或在您的DbContext 中使用DbSet 并做更多“让实体框架为您构建查询的正常方式。


* 从技术上讲,您可以通过在结果上调用 AsQueryable(),但这只是一个伪装成 IQueryable 的 IEnumerable,它不会为您提供使用“真实”IQueryable 的任何好处,例如仅检索来自服务器的所需行。

【讨论】:

  • “正常”方式只有在我做简单的事情时才有可能。并非软件开发中的一切都是直截了当的。无论如何。感谢您的回答,至少现在我知道我无法从 SQL 查询中获取 IQueryable。
  • @1576573987 我认为您正在陷入XY Problem,我建议您提出一个新问题,解释为什么您认为“正常”方式行不通,并询问您是否缺少某些东西这会让它工作。
  • @ScottChamberlain 我已经尝试过解决它并引发this 异常(调用ToArrayAsync 时),我将其返回为IAsyncEnumerable&lt;T&gt;,可以使用System.Linq.AsyncEnumerable 进行操作扩展方法。
【解决方案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 @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 查询中起作用(不一定是存储的过程/函数调用)。
  • 通常会将原始 Sql 放入子查询中。因此,请确保它对此类内容有效(即分号、排序方式、提示等可能会导致问题)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-22
    • 1970-01-01
    • 2014-11-09
    • 2021-06-20
    • 2017-02-19
    • 1970-01-01
    • 2021-04-05
    • 2011-07-23
    相关资源
    最近更新 更多