Exceptions leading to failure in AdonetAppender.DoAppend: Pattern layout in log4net

If you use log4net then you have to be careful of using patternlayouts for parameters for Adonetappenders.  Log4net can work with all native .net datatypes including nullables.  However, a layout like this:
<parameter>
        <parameterName value=”@UidSubmission”/>
        <dbType value=”Int32″/>
        <layout type=”log4net.Layout.PatternLayout”>
          <conversionPattern value=”%X{uidsubmission}” />
        </layout>
      </parameter>

while valid for a simple type like an int, may generate an exception if it is a nullable or reference type.  This is because patternlayout infers a cast to string when binding parameters.  If the value of the parameter is null, that tostring cast will fail.  They make no mention of that in the patternlayout documentation that is here.  For reference types and nullables you would be better served by using a rawpropertylayout.  This binds directly to the datatype and does not do any casting.  The syntax is a bit unusual (it helps to bind to the log4net.xsd so you can see how to use this).  An example of such a parameter is below:
   <parameter>
        <parameterName value=”@DischargeDate”/>
        <dbType value=”DateTime” />
        <layout type=”log4net.Layout.RawPropertyLayout”>
          <key value=”dischargedate”/>
          </layout>
      </parameter>    
The error you will get in your log4net logs will look like this:
og4net:ERROR [AdoNetAppender] Failed in DoAppend
System.Data.SqlClient.SqlException: Error converting data type nvarchar to datetime.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at log4net.Appender.AdoNetAppender.SendBuffer(IDbTransaction dbTran, LoggingEvent[] events)
   at log4net.Appender.AdoNetAppender.SendBuffer(LoggingEvent[] events)
   at log4net.Appender.BufferingAppenderSkeleton.Append(LoggingEvent loggingEvent)
   at log4net.Appender.AppenderSkeleton.DoAppend(LoggingEvent loggingEvent)