Dapper 错误“字符串或二进制数据将被截断。”

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

我收到错误“字符串或二进制数据将被截断”。运行以下代码行时。我无法确定原因,并且我搜索的有关此错误的所有内容都与插入有关,例如超出了数据库表上的 vhar 限制。数据库的数据类型将对象字符串与 nvarchar、DateTime 与 datetime 等相匹配。下面的代码行遵循下面的查询,并且是引发错误的地方。

var 结果 = (等待连接.QueryAsync(commandDefinition)).ToList();

堆栈跟踪

   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows)
   at System.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more)
   at System.Data.SqlClient.SqlDataReader.<>c__DisplayClass190_0.<ReadAsync>b__1(Task t)
   at System.Data.SqlClient.SqlDataReader.InvokeRetryable[T](Func`2 moreFunc, TaskCompletionSource`1 source, IDisposable objectToDispose)
--- End of stack trace from previous location ---
   at Dapper.SqlMapper.<QueryAsync>d__33`1.MoveNext()
   at OQCESIResultsUrl.Repository.OqcRepository.<GetStoredUrlsForManufacturingItemAsync>d__3.MoveNext() in ...
   at OQCESIResultsUrl.Repository.OqcRepository.<GetStoredUrlsForManufacturingItemAsync>d__3.MoveNext() in ...
   at OQCESIResultsUrl.UrlProviders.OqcUrlProvider.<ProvideUrlsForMeasurementAsync>d__2.MoveNext() in ...
   at OQCESIResultsUrl.UrlProviders.MasterUrlProvider.<ProvideUrlsAsync>d__3.MoveNext() in ...
   at OQCESIResultsUrl.Services.EsiResultsUrlRetrievalService.<GetEsiResultsUrlByMfgItemIds>d__2.MoveNext() in ...
   at Program.<>c.<<<Main>$>b__0_6>d.MoveNext() in ...

正在运行的查询如下

await using var connection = GetOpenConnection(OQCDomain);
var commandDefinition = new CommandDefinition(@" 
                SELECT CASE WHEN ser.PromassDirectoryPath IS NOT NULL OR ser.PromassDirectoryPath != '' THEN '' 
                    ELSE 'No record found'
                    END [ErrorMessage], 
                    CASE WHEN ser.PromassDirectoryPath IS NOT NULL OR ser.PromassDirectoryPath != '' THEN 1 
                    ELSE 0
                    END [Success], 
                    ser.PromassDirectoryPath [Url], 
                    ser.ProcessingDateTime, 
                    s.MfgItemId
                FROM dbo.Sample AS s WITH (NOLOCK)
                    LEFT JOIN dbo.SampleESIResult AS ser WITH (NOLOCK) ON ser.SampleESIResultId = s.SampleESIResultId
                    LEFT JOIN dbo.QCProcessHistory AS QPH WITH (NOLOCK) ON s.QCContainerId = QPH.QCContainerId
                WHERE s.MfgItemId IN (@manufacturingItemId)
                    AND QPH.QCStatusId = 9 /* ESI Reviewed */
                GROUP BY s.MfgItemId, ser.ProcessingDateTime, ser.PromassDirectoryPath",
    parameters: new
    {
        manufacturingItemId = string.Join(',', measurementDetail)
    },
    cancellationToken: cancellationToken);

当直接在数据库上运行查询时,查询确实可以工作,给出所有预期结果。

它尝试映射到的对象是

public class OutputWithIds
{
    public string? ErrorMessage { get; set; }
    public bool Success { get; set; }
    public string? Url { get; set; }
    public DateTime? ProcessingDateTime { get; set; }
    public int? MfgItemId { get; set; }
}

数据库中的数据类型 制造项目 ID = int 处理日期时间 = 日期时间 网址 nvarchar(256)

如有任何帮助,我们将不胜感激。谢谢!

我尝试删除除一个选择列之外的所有列,以尝试缩小导致问题的范围,但所有列都抛出错误。

c# sql asp.net dapper
1个回答
0
投票

我不确定带有虚拟字段的 SQL Server 的行为,但根据我在其他数据库中的经验,它可能与您的虚拟字段相关

[ErrorMessage]

试着一步一步地思考。 SQL Server 尝试从数据库中提取第一行,并且在列

ser.PromassDirectoryPath
中具有一些值。因此,在虚拟字段 [ErrorMessage] 中,您将具有空值,即 null,即 CHAR(0) 或 CHAR(1)。 在第二行中,
ser.PromassDirectoryPath
列中没有值,SQL Server 尝试将字符串行“未找到记录”放入虚拟字段中,众所周知,虚拟字段的类型为 CHAR(0)。

那么,也许可以将此虚拟列的数据类型强制转换为 CHAR(50)? 像这样的东西:

        SELECT CONVERT(CHAR(50), CASE WHEN ser.PromassDirectoryPath IS NOT NULL OR ser.PromassDirectoryPath != '' THEN '' 
            ELSE 'No record found'
            END [ErrorMessage]), 
            CASE WHEN ser.Promas

我不确定 SQL Server 的语法是否正确,但我希望我很清楚。

© www.soinside.com 2019 - 2024. All rights reserved.