【发布时间】:2019-11-25 16:32:59
【问题描述】:
问题:
在 C#、带有 Angular 6 前端的 IIS 部署解决方案上的 MVC API。
一个在特定列上有 8 个过滤字段的简单 HTML 表通过 API HttpGet 调用在后端运行查询。该函数本身可以正常工作,但对于特定字符串 NOT。例如,在“描述”字段上,后端返回“数据为空”。使用以下字符串时,无法对 Null 值调用此方法或属性。值在前端和后端之间正确传递,API 调用大多返回适当的数据。
但是,app 和比 app 更长的字符串(例如 application、cert 和更长的字符串(例如 certificate)将返回“Data is Null”错误。
如果我使用f 作为transmittal 的输入,我会收到“数据为空”错误。
但是,如果我在 document 上使用 crc 并且 THEN 使用 f 作为 transmittal 的输入,则函数返回正常数据??
这只发生在部署状态下,调试代码时不会出现问题。调试时,代码会返回预期的结果并始终产生正确的响应。
使用一组“链式” where 语句构建 IQueryable 的服务调用,该 IQueryable 被调用以在序列末尾返回 .ToListAsync()。
使用:
- IIS,版本 10,在虚拟机上运行
- 操作系统 IIS 虚拟机:Windows Server 2016
- .Net 核心:2.1
- EntityFrameworkCore:2.1.11
- SQL Server 2012(在同一虚拟机上运行)
- VS 2019
- SQL Server Management Studio 2018
控制器代码
[HttpGet("[action]")]
public async Task<IActionResult> Search(string TR, string DA, string DO, string RE, string TY, string DD, string DI, string OR, string DE)
{
return Ok(await _archiveService.Search(TR, DA, DO, RE, TY, DD, DI, OR, DE));
}
ArchiveService 代码
public async Task<IEnumerable<object>> Search(
string transmittal,
string date,
string document,
string revision,
string type,
string description,
string discipline,
string origin,
string destination)
{
var result = _db.TblCorrespondenceLog.AsQueryable();
if (!string.IsNullOrEmpty(transmittal))
result = result.Where(f => f.TransmittalNo.Contains(transmittal));
if (!string.IsNullOrEmpty(date))
{
}
if (!string.IsNullOrEmpty(document))
result = result.Where(f => f.CompanyDocumentNo.ToLower().Contains(document));
if (!string.IsNullOrEmpty(type))
result = result.Where(f => f.DocumentType.ToLower() == type);
if (!string.IsNullOrEmpty(description))
result = result.Where(f => f.DocumentDescription.ToLower().Contains(description));
if (!string.IsNullOrEmpty(discipline))
result = result.Where(f => f.Discipline.ToLower() == discipline);
if (!string.IsNullOrEmpty(origin))
result = result.Where(f => f.OriginatorCode.ToLower() == origin);
if (!string.IsNullOrEmpty(destination))
result = result.Where(f => f.SupplierCode.ToLower() == destination);
return await result.ToListAsync();
}
给出错误的字段是具有.Contains() 子句的字段
当我使用 SQL 编写器获取发送到服务器的查询时,我得到以下查询,这会在调用 .ToListAsync() 时导致“数据为空”错误:
SELECT [f].[uID], [f].[Action_Required], [f].[Approved_Responded], [f].[Area_Code], [f].[Company_Document_No],
[f].[Discipline], [f].[Document_Description], [f].[Document_Type], [f].[fileUID], [f].[Link], [f].[Originator_Code],
[f].[Reference_Document], [f].[ResponsibelEngineer], [f].[ResubDate], [f].[ResubTransmittal], [f].[Rev],
[f].[Sequential_Number], [f].[Sheet_Number], [f].[Supplier_Code], [f].[TDate], [f].[Transmittal_Date], [f].[Transmittal_No],
[f].[Transmittal_Type], [f].[TRN_Originator], [f].[TurnAroundDate], [f].[Unit_Code],
[f].[TransmitUID]
FROM [tblCorrespondenceLog] AS [f]
WHERE CHARINDEX(N'f', [f].[Transmittal_No]) > 0
当从 SMSS (SQL Server Management Studio 2018) 触发时,哪个工作得很好?
如果我使用crc 作为document 的输入,我会正常返回数据,但查询只是略有不同:
SELECT [f].[uID], [f].[Action_Required], [f].[Approved_Responded], [f].[Area_Code], [f].[Company_Document_No],
[f].[Discipline], [f].[Document_Description], [f].[Document_Type], [f].[fileUID], [f].[Link], [f].[Originator_Code],
[f].[Reference_Document], [f].[ResponsibelEngineer], [f].[ResubDate], [f].[ResubTransmittal], [f].[Rev],
[f].[Sequential_Number], [f].[Sheet_Number], [f].[Supplier_Code], [f].[TDate], [f].[Transmittal_Date], [f].[Transmittal_No],
[f].[Transmittal_Type], [f].[TRN_Originator], [f].[TurnAroundDate], [f].[Unit_Code],
[f].[TransmitUID]
FROM [tblCorrespondenceLog] AS [f]
WHERE (CHARINDEX(N'f', [f].[Transmittal_No]) > 0) AND (CHARINDEX(N'crc', LOWER([f].[Company_Document_No])) > 0)
所以... 为什么实体框架只在特定字符串和特定组合上给我一个“数据为空”错误。即使对“问题”字段进行过滤(当然使用不同的字符串),该函数也会在哪里返回正确的值?
【问题讨论】:
-
您通常不想在查询中调用
.ToLower(),因为它永远不会在数据库服务器上运行,因此效率非常低。 -
@poke 我已添加该内容以尝试解决此问题。在此之前(即没有 ToLower())查询的响应是否相同?而且,如前所述,对于某些查询字符串,该方法可以正常工作 - 如果可能效率低下 -。它是针对非常特定的字符串而失败的?
-
您是否尝试过使用 SQL Profiler 来确保对您的数据库执行 sql 查询?此外,对于已部署的网站,请确保数据库用户对 tblCorrespondenceLog 表具有选择权限。
-
请确保查询返回的数据不为空。并且您正在使用与 iis 相同的数据库?
-
@MohsinMehmood 是的,我已经尝试在同一个生产数据库上的 SMSS 上运行查询。 EntityFramework 生成的 SQL 在数据库上直接调用时会产生正确的结果。但是,相同的数据在 .ToListAsync() 调用上转换为列表时会出错。用户名等都相同,所以这不是问题,因为查询 - 如所示 - 大多返回正确的结果
标签: sql entity-framework asp.net-core-mvc iis-10