Shu*_*ari 6 c# linq sql-server entity-framework entity-framework-core
我有一个用例,其中我将查询传递给函数,然后进行一些计算。查询是根据我通过的过滤器形成的。下面是示例代码
var totalCount = await query.CountAsync();
var limitExceeded = limit.HasValue && totalCount > limit.Value;
var pagedResults = new List<R>();
// Don't execute the query if the limit has been exceeded
if (!limitExceeded)
{
//Do some work here
}
Run Code Online (Sandbox Code Playgroud)
我面临的问题是有一个名为“filename”的过滤器,当我通过该过滤器时,生成的底层查询如下所示
DECLARE @__fileName_1 nvarchar(1024) = N'%cmder.zip%';
SELECT [d].[Id], [d].[CreatedByUserId], [d].[DateCreated], [d].[DateModified], [d].[DatePurged], [d].[Deleted], [d].[DocumentKey], [d].[DocumentStatusId], [d].[DocumentTypeId], [d].[FileDesc], [d].[FileExt], [d].[FileLength], [d].[FileLengthTypeId], [d].[FileName], [d].[FileSize], [d].[FullPath], [d].[Hidden], [d].[ModifiedByUserId], [d].[PurgedByUserId], [d].[RepositoryId], [d].[SHA1], [d].[TransactionId], [d].[UploadedDate], [c].[Id], [c].[CaseId], [c].[DateModified], [c].[Deleted], [c].[DocumentId], [c].[ModifiedByUserId], [c].[PublishToId], [c].[TransactionId], [c0].[Id], [c0].[CaseCoordinatorId], [c0].[CaseName], [c0].[CaseNo], [c0].[CaseTypeId], [c0].[CaseVenueTypeId], [c0].[County], [c0].[Court], [c0].[DateModified], [c0].[DateSettled], [c0].[Deleted], [c0].[Disabled], [c0].[FullCaseName], [c0].[IsComplex], [c0].[IsDepository], [c0].[ModifiedByUserId], [c0].[NameKey], [c0].[Remarks], [c0].[SalesRepId], [c0].[TransactionId], [c0].[TrialDate], [c0].[USStateId], [l].[Name] AS [PublishTo], N'Case' AS [Level]
FROM [Documents].[Document] AS [d]
INNER JOIN [Orders].[CaseDocument] AS [c] ON [d].[Id] = [c].[DocumentId]
INNER JOIN [Orders].[Case] AS [c0] ON [c].[CaseId] = [c0].[Id]
INNER JOIN [Admin].[LookupValue] AS [l] ON [c].[PublishToId] = [l].[Id]
WHERE [d].[FileName] LIKE @__fileName_1
ORDER BY [d].[UploadedDate] DESC
Run Code Online (Sandbox Code Playgroud)
现在,这个查询在 SQL Server Management Studio 上运行得非常快,但是当我调试 C# 代码时,一旦执行命中,await query.CountAsync()
它就开始在 UI 上加载,然后在一段时间后超时。有人可以帮我调试这个吗?当我发送其他过滤器(例如日期)时,它工作正常,但是当我发送名称时,它开始花费时间,但仅在 C# 端,因为我已经检查生成的查询运行得相当快。
由于文档表中有很多行,因此您正在对整个表进行不可控制扫描!这并不理想。理想情况下,您希望使其可控制,因此请删除前导或尾随的 % 符号。
例如,如果您删除前导 %,那么它将能够在 FirstName 列上使用索引(只要您创建一个索引)。然后它可以寻求匹配并只读取该数据而不是整个表。
你可以在你的 linq 代码中尝试这样的事情
YourDocuments.Where(x => EF.Functions.Like(x.FileName, $"{yourSearchString}%"))
Run Code Online (Sandbox Code Playgroud)
如果您想要更多的控制权,请考虑存储过程,但如果这能完成工作,那么一切都很好:)
如果您刚刚在 FileName 上创建了一个索引并保留了 %...% 语法,它可能会使用上面其他人提到的索引,它仍然会对该索引进行完整扫描。该索引将小于聚集索引表,这也是 SQL Server 使用它的原因,因为它将执行更少的逻辑页读取。
归档时间: |
|
查看次数: |
1577 次 |
最近记录: |