我正在调试应用程序中的间歇性截断错误。我的日志中的错误如下所示:
System.Data.SqlClient.SqlException: String or binary data would be truncated.
The statement has been terminated. Generated: Tue, 02 Nov 2010 03:55:18 GMT
NHibernate.Exceptions.GenericADOException: could not insert:
[DataModel.Product][SQL: INSERT INTO [Product] (Fields) VALUES (?, ?,...);
select SCOPE_IDENTITY()] --->
System.Data.SqlClient.SqlException: String or binary data would be truncated.
The statement has been terminated.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
请注意,错误不会为抛出错误的sql提供参数值,只提供占位符:(?, ?,...)
。有没有办法从nHibernate获取这些?像这样:
try {
...
Session.Flush(); // throws
}
catch (GenericADOException ex) {
// want to get the bad parameter values,
// so I can re-throw a more helpful exception
}
答案 0 :(得分:6)
大多数情况下,当被投放的数据的字符数多于字段长度时,此string or binary data truncated....
来自Nhibernate
Ado异常。例如如果表db字段为nvarchar(50)
,但正在努力插入超过50个字符,则会发生此异常。解决方案是增加表Db字段长度或减少插入的数据字符。
答案 1 :(得分:2)
您可以设置一个IPreInsertEventListener,在插入之前循环遍历字符串属性,检查它们的长度。
如果其中一个属性太长,您可以记录属性的名称及其值。
答案 2 :(得分:1)
您可以深入了解nHibernate Profiler的内容。
答案 3 :(得分:1)
您可以配置log4net以在某处发送NH SQL输出。例如:
<log4net>
<appender name="Debug" type="log4net.Appender.DebugAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %message%newline" />
</layout>
</appender>
<logger name="NHibernate.SQL">
<level value="DEBUG"/>
<appender-ref ref="Debug"/>
</logger>
</log4net>
在这种情况下,我将它发送到Debug窗口。
答案 4 :(得分:0)
最好的解决方案似乎是事件监听器,它验证SQL中使用的值(它独立于DB工作,即使SQLite忽略了长度约束)。我写了一篇博文,其中描述了如何实现这样的监听器https://cezarypiatek.github.io/post/validate-fields-in-nhibernate-model/