在nHibernate中调试“字符串或二进制数据将被截断”错误

时间:2010-11-02 23:24:33

标签: c# database nhibernate validation

我正在调试应用程序中的间歇性截断错误。我的日志中的错误如下所示:

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
}

5 个答案:

答案 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/