log4net AdoNetAppender 在数据库中插入 "Null" 字符串而不是空值
log4net AdoNetAppender inserting "Null" string instead of null in database
我的 .net 3.5 应用程序上有一个 log4net 日志。日志记录正在插入数据库。我遇到的一个问题是,对于我没有设置数据的数据库,它插入 "NULL" 而不是数据库 null。
我的配置是
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<immediateFlush value="true" />
<bufferSize value="0" />
<connectionType value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" />
<connectionString value="data source=localhost;initial catalog=logging_db;User ID=root;Password=" />
<commandText value="INSERT INTO system_log(appname, action,context_id)
VALUES (@appname, @action, @context_id);" />
<parameter>
<parameterName value="appname" />
<dbType value="String" />
<size value="10" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="My Web Service" />
</layout>
</parameter>
<parameter>
<parameterName value="action" />
<dbType value="String" />
<size value="45" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%5c{1}.%M" />
</layout>
</parameter>
<parameter>
<parameterName value="context_id" />
<dbType value="String" />
<size value="48" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%X{context_id}" />
</layout>
</parameter>
<filter type="log4net.Filter.LevelRangeFilter">
<acceptOnMatch value="true" />
<levelMin value="DEBUG" />
<levelMax value="FATAL" />
</filter>
</appender>
在某些方法中,我在我的方法中将 context_id 设置为
log4net.LogicalThreadContext.Properties["context_id"] = "My context";
在我提供的地方插入正常,但在我没有设置的地方插入错误。
我也在 https://issues.apache.org/jira/browse/LOG4NET-28 检查了这个问题,但它被标记为已解决
您可以更改 INSERT INTO 语句以检查 "NULL" 字符串并将它们替换为 DB 空值,这个想法来自
所以它看起来像这样:
INSERT INTO system_log(appname, action,context_id) VALUES (@appname, @action, CASE WHEN @context_id = 'NULL' THEN NULL ELSE @context_id END );"
更新
要改用存储过程,只需像这样替换您的语句:
exec YourStoredProcedure @appname, @action, @context_id
对于这种情况,我更喜欢使用触发器。 ON INSERT 或 INSTEAD OF INSERT(参见 https://technet.microsoft.com/en-us/library/ms175089(v=sql.105).aspx)
我会做类似的事情:
CREATE TRIGGER dbo.log_onInsert
ON system_log
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO system_log(appname, action,context_id)
select
appname, action,
case when inserted.context_id='(null)' then null else inserted.context_id end
from inserted
END
GO
尝试以下操作:
<layout type="log4net.Layout.RawPropertyLayout">
<key value="yourParameterName" />
</layout>
而不是:
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="yourParameterName" />
</layout>
至少在我的情况下它有所帮助并且 log4net 将 NULL 值插入到列中
我的 .net 3.5 应用程序上有一个 log4net 日志。日志记录正在插入数据库。我遇到的一个问题是,对于我没有设置数据的数据库,它插入 "NULL" 而不是数据库 null。 我的配置是
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<immediateFlush value="true" />
<bufferSize value="0" />
<connectionType value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" />
<connectionString value="data source=localhost;initial catalog=logging_db;User ID=root;Password=" />
<commandText value="INSERT INTO system_log(appname, action,context_id)
VALUES (@appname, @action, @context_id);" />
<parameter>
<parameterName value="appname" />
<dbType value="String" />
<size value="10" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="My Web Service" />
</layout>
</parameter>
<parameter>
<parameterName value="action" />
<dbType value="String" />
<size value="45" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%5c{1}.%M" />
</layout>
</parameter>
<parameter>
<parameterName value="context_id" />
<dbType value="String" />
<size value="48" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%X{context_id}" />
</layout>
</parameter>
<filter type="log4net.Filter.LevelRangeFilter">
<acceptOnMatch value="true" />
<levelMin value="DEBUG" />
<levelMax value="FATAL" />
</filter>
</appender>
在某些方法中,我在我的方法中将 context_id 设置为
log4net.LogicalThreadContext.Properties["context_id"] = "My context";
在我提供的地方插入正常,但在我没有设置的地方插入错误。 我也在 https://issues.apache.org/jira/browse/LOG4NET-28 检查了这个问题,但它被标记为已解决
您可以更改 INSERT INTO 语句以检查 "NULL" 字符串并将它们替换为 DB 空值,这个想法来自
所以它看起来像这样:
INSERT INTO system_log(appname, action,context_id) VALUES (@appname, @action, CASE WHEN @context_id = 'NULL' THEN NULL ELSE @context_id END );"
更新
要改用存储过程,只需像这样替换您的语句:
exec YourStoredProcedure @appname, @action, @context_id
对于这种情况,我更喜欢使用触发器。 ON INSERT 或 INSTEAD OF INSERT(参见 https://technet.microsoft.com/en-us/library/ms175089(v=sql.105).aspx)
我会做类似的事情:
CREATE TRIGGER dbo.log_onInsert
ON system_log
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO system_log(appname, action,context_id)
select
appname, action,
case when inserted.context_id='(null)' then null else inserted.context_id end
from inserted
END
GO
尝试以下操作:
<layout type="log4net.Layout.RawPropertyLayout">
<key value="yourParameterName" />
</layout>
而不是:
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="yourParameterName" />
</layout>
至少在我的情况下它有所帮助并且 log4net 将 NULL 值插入到列中