几天前问过这个问题,但也许并不太具体。
基本上,我正在编写一个接受存储过程名称列表并随意执行它们的控制台应用程序。该应用程序应该记录Slack等关于这些sprocs的进展,以及稍后做其他一些事情。
其他东西'我提到了与已知数据库模型的交互,因为我们有一个ServiceStack / OrmLite类型库,所以我以后使用OrmLite与数据库进行交互。
因此,由于我在项目中包含并配置了OrmLite,我只是使用OrmLite IDbConnection
来执行存储过程,即使它仅仅是名称。 sprocs只是将数据移动到另一个数据库,一个应用程序不需要与之交互的数据库 - 所以我没有SELECT
使用sprocs将任何数据PRINT
添加到应用程序中。没有POCO表示移动了什么。
然而,sprocs吐出了许多我想捕获的信息性Ormlite
语句,并通过Slack以格式化方式登录我们的团队。启用完整的调试日志记录会为此目的提供一些过多的信息。
我有什么方法可以配置SqlServerDialect.Provider
IDataReader
,SqlInfoMessageEventHandler
等基本上捕获SqlConnection.InfoMessage
事件(或为其提供已准备好<div class="example-container">
<mat-form-field>
<input matInput formControlName="Id_Product" placeholder="Producto" class="form-control" id="Id_Product" [formControl]="myControl" [matAutocomplete]="auto" required>
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let option of filteredProducts | async" [value]="option.NameProduct">
{{ option.NameProduct }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div class="color-required" *ngIf="FormDetailProductCreate.get('Id_Product').touched && FormDetailProductCreate.get('Id_Product').invalid">
Producto es requerido
</div>
</div>
<div class="example-container">
<mat-form-field>
<input matInput formControlName="Id_TypeProduct" placeholder="Tipo de producto" class="form-control" id="Id_TypeProduct" [formControl]="myControl" [matAutocomplete]="auto" required>
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let option of filteredTypeProducts | async" [value]="option.NameTypeProduct">
{{ option.NameTypeProduct }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div class="color-required" *ngIf="FormDetailProductCreate.get('Id_TypeProduct').touched && FormDetailProductCreate.get('Id_TypeProduct').invalid">
Tipo de producto es requerido
</div>
</div>
<div class="example-container">
<mat-form-field>
<input matInput formControlName="Id_Provider" placeholder="Proveedor" class="form-control" id="Id_Provider" [formControl]="myControl" [matAutocomplete]="auto" required>
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let option of filteredProviders | async" [value]="option.NombreProveedor">
{{ option.NombreProveedor }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div class="color-required" *ngIf="FormDetailProductCreate.get('Id_Provider').touched && FormDetailProductCreate.get('Id_Provider').invalid">
Proveedor es requerido
</div>
</div>
的连接)?
答案 0 :(得分:2)
执行此操作的日志记录策略方法是在日志记录提供程序中配置过滤器,以仅记录您感兴趣的邮件。
包含SQL和DB参数的OrmLite SQL调试日志消息记录在ServiceStack.OrmLite.OrmLiteResultsFilterExtensions
类型下。
为了简化此方案,我刚刚添加了新的OrmLiteConfig.BeforeExecFilter
和OrmLiteConfig.AfterExecFilter
,您可以在执行DB命令之前和之后执行自定义逻辑,例如:
OrmLiteConfig.BeforeExecFilter = dbCmd => Console.WriteLine(dbCmd.GetDebugString());
此更改现在可从v5.0.3获取,现在为available on MyGet。
答案 1 :(得分:1)
查看ServiceStack.OrmLite源代码,看起来IDbConnection
可以使用SqlConnection
转换为(SqlConnection)IDbConnection.ToDbConnetion()
。
在OrmLiteExecFilter
中将其包含在每个语句中进行调用,强制转换IDbConnection
并使用强制转换连接创建DbCommand
对我有用:
public class LogInfoMessageFilter : OrmLiteExecFilter
{
ILog SlackLog = LogManager.GetLogger("SlackLogger");
public override T Exec<T>(IDbConnection dbConn, Func<IDbCommand, T> filter)
{
var holdProvider = OrmLiteConfig.DialectProvider;
// casting, skipping type checks for brevity
var sqlConn = (SqlConnection)dbConn.ToDbConnection();
// add the event
sqlConn.InfoMessage += _HandleInfoMessage;
var dbCmd = CreateCommand(sqlConn);
try
{
return filter(dbCmd);
}
finally
{
DisposeCommand(dbCmd, sqlConn);
OrmLiteConfig.DialectProvider = holdProvider;
}
}
private void _HandleInfoMessage(object sender, SqlInfoMessageEventArgs args)
{
SlackLog.Info($"what does the sproc say? {args.Message}");
}
}
// before opening the connection:
OrmLiteConfig.ExecFilter = new LogInfoMessageFilter();
然而,现在@mythz回复了一位官员&#39;这样做的方法,我将进行重构。我以为我会把它放在这里,以防它适合任何人的使用案例。