为什么 Entity Framework Core 要求 ContainsTable() 排序依据为“前 200 个”?

问题描述 投票:0回答:1

在 SSMS 中,以下查询工作正常,返回预期的 1 行:

SELECT * 
FROM CONTAINSTABLE(AppUsers, *, 'hick', 200) AS t 
INNER JOIN AppUsers u ON u.Id = t.[KEY] 
ORDER BY t.[RANK] DESC

但是当我使用实体框架调用以下内容时,完全相同的选择:

listUsers = await dbContext.AppUsers.FromSqlInterpolated(
        $@"SELECT * FROM CONTAINSTABLE(AppUsers, *, {Query}, 200) as t INNER JOIN AppUsers u on u.Id = t.[KEY] ORDER BY t.[RANK] desc")
        .ToListAsync();

我遇到了一个例外:

Microsoft.EntityFrameworkCore.Query:错误:迭代上下文类型“LouisHowe.core.Data.NoTrackingDbContext”的查询结果时发生异常。

Microsoft.Data.SqlClient.SqlException (0x80131904):ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP、OFFSET 或 FOR XML。

在 Microsoft.Data.SqlClient.SqlCommand.<>c.b__208_0(任务

1 result)   at System.Threading.Tasks.ContinuationResultTaskFromResultTask
2.InnerInvoke()
在 System.Threading.ExecutionContext.RunInternal(ExecutionContextexecutionContext,ContextCallback 回调,对象状态)
--- 先前位置的堆栈跟踪结束 ---
在 System.Threading.ExecutionContext.RunInternal(ExecutionContextexecutionContext,ContextCallback 回调,对象状态)
在System.Threading.Tasks.Task.ExecuteWithThreadLocal(任务&currentTaskSlot,线程threadPoolThread)
--- 先前位置的堆栈跟踪结束 ---
在Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject参数对象,CancellationToken取消令牌)
在Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject参数对象,CancellationToken取消令牌)
在 Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable
1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func
4 操作中,Func
4 verifySucceeded, CancellationToken cancellationToken)   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable
1.AsyncEnumerator.MoveNextAsync()

客户端连接 ID:34a279b8-9257-4414-b7d0-b0a3c135a4db
错误号:1033,状态:1,类别:15

现在可以了:

listUsers = await dbContext.AppUsers.FromSqlInterpolated(
        $@"SELECT top 200 * FROM CONTAINSTABLE(AppUsers, *, {Query}, 200) as t INNER JOIN AppUsers u on u.Id = t.[KEY] ORDER BY t.[RANK]")
        .ToListAsync();

但是为什么我必须在将

top 200
传递给
200
时添加
CONTAINSTABLE()

sql-server entity-framework-core full-text-search
1个回答
0
投票

答案就在这里

使用 LINQ 进行组合需要您的 SQL 查询是可组合的,因为 EF Core 会将提供的 SQL 视为子查询。可组合的 SQL 查询 一般以SELECT关键字开头,不能包含SQL 在子查询中无效的功能,例如:

  • 在 SQL Server 上,ORDER BY 子句不与 SELECT 子句中的 OFFSET 0 OR TOP 100 PERCENT 一起使用
© www.soinside.com 2019 - 2024. All rights reserved.