![](/img/trans.png)
[英]Parameterized OPENJSON in SQL Server query using Entity Framework Core
[英]Entity Framework Core; using ORDER BY in query against a (MS) SQL Server
我正在尝试对Microsoft SQL Server 2016将以下查询与Entity Framework Core结合使用:
SELECT [a], [b], [c]
FROM [x]
WHERE [a] = {0}
ORDER BY [b]
我这样使用此查询:
context.MySet.AsNoTracking()
.FromSql(MyQuery, aValue)
.Skip(pageSize * page)
.Take(pageSize)
.Select(x => x.ToJsonDictionary())
.ToList()
我在带有分页功能的.NET Core REST API中使用了此功能,并且希望对记录进行排序(按字母顺序),以使分页功能更加有用。 执行以上语句时出现以下错误:
除非还指定了TOP,OFFSET或FOR XML,否则ORDER BY子句在视图,内联函数,派生表,子查询和公共表表达式中无效.FETCH语句中选项NEXT的无效用法。 除非还指定了TOP,OFFSET或FOR XML,否则ORDER BY子句在视图,内联函数,派生表,子查询和公共表表达式中无效.FETCH语句中选项NEXT的无效用法。
寻找类似的问题,我发现这些一些其他职位( 1 , 2 , 3 ),但其中没有一个与EF核心的组合,其中使用和/或它们在不同的环境中使用它不以我的情况下(例如,子查询)申请。
我试图在查询中使用EF的.OrderBy(..)
语法,而不是在ORDER BY
中使用,但这不能解决问题。 我还尝试将查询中的SELECT
之后的TOP 100 PERCENT
与ORDRE BY
结合使用; 这行得通,但没有订购该专栏。 它只是被忽略了。 此限制在EF限制下进行描述。 我还发现此帖子用TOP 99.99 PERCENT...
或TOP 9999999...
代替TOP 100 PERCENT...
这似乎应该起作用,但是并不“感觉”正确。 一般而言,此问题将在此处进一步说明。
摘要:建议不要在View中使用ORDER BY。 在视图外使用ORDER BY。 实际上,正确的设计意味着相同。 如果将TOP与Views一起使用,则很有可能View不会返回表的所有行或将完全忽略ORDER BY。
此外,我对“视图”一词感到困惑。 对我而言,术语“视图”是指使用CREATE VIEW ..
语法CREATE VIEW ..
。 普通的“正常” SQL查询是否也被视为视图? 还是EF Core将请求包装在某种视图中,这才是导致此错误的真正问题?
我不确定,但是到目前为止,我发现的所有“解决方案”似乎都有些“ hacky”。 思考?
让我们简化一下。 这就是我要进行测试的内容。 我还添加了一些代码,用于打印从EF查询生成的sql 。
class Program
{
static void Main(string[] args)
{
DbClient context = new DbClient();
var rawSql = "select [Id], [Title] from Post order by [Title]";
var query = context.Posts.AsNoTracking()
.FromSql(rawSql)
.Skip(1)
.Take(4)
.OrderBy(x => x.Title);
var generated = query.ToSql();
var results = query.ToList();
}
}
class DbClient : DbContext
{
public DbSet<Post> Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("conn_string");
}
}
class Post
{
public int Id { get; set; }
public string Title { get; set; }
public override string ToString() => $"{Id} | {Title}";
}
当我们查看generated
的值时,我们看到query
的sql是:
SELECT [t].[Id], [t].[Title]
FROM (
SELECT [p].[Id], [p].[Title]
FROM (
select [Id], [Title] from Post order by [Title]
) AS [p]
ORDER BY (SELECT 1)
OFFSET 1 ROWS FETCH NEXT 4 ROWS ONLY
) AS [t]
ORDER BY [t].[Title]
请注意,存在三个order by
子句,最里面的一个是rawSql
的一个。
我们可以查看错误消息以了解为什么它不合法:
除非也指定了偏移[...],否则ORDER BY子句在子查询[...]中无效。
中间顺序by 确实包含偏移量,因此即使它在子查询中也有效。
要解决此问题,只需从rawSql
删除顺序并继续使用OrderBy()
linq方法。
var rawSql = "select [Id], [Title] from Post";
var query = context.Posts.AsNoTracking()
.FromSql(rawSql)
.Skip(1)
.Take(4)
.OrderBy(x => x.Title);
这将产生:
SELECT [t].[Id], [t].[Title]
FROM (
SELECT [p].[Id], [p].[Title]
FROM (
select [Id], [Title] from Post
) AS [p]
ORDER BY (SELECT 1)
OFFSET 1 ROWS FETCH NEXT 4 ROWS ONLY
) AS [t]
ORDER BY [t].[Title]
现在,所有order by子句都不在子查询中,或者没有offset子句。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.