我正在尝试在Windows窗体应用程序中实现日志记录,并且我有这段代码,可以让我在使用Entity Framework 6时拦截CRUD操作:
class EFCommandInterceptor : IDbCommandInterceptor
{
public void NonQueryExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
LogInfo("NonQueryExecuted", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText));
}
public void NonQueryExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
LogInfo("NonQueryExecuting", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText));
}
public void ReaderExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
{
LogInfo("ReaderExecuted", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText));
}
public void ReaderExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
{
LogInfo("ReaderExecuting", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText));
}
public void ScalarExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
LogInfo("ScalarExecuted", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText));
}
public void ScalarExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
LogInfo("ScalarExecuting", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText));
}
private void LogInfo(string command, string commandText)
{
Console.WriteLine("Intercepted on: {0} :- {1} ", command, commandText);
}
}
然后我像这样添加拦截器:
public class FE6CodeConfig : DbConfiguration
{
public FE6CodeConfig()
{
this.AddInterceptor(new EFCommandInterceptor());
}
}
现在这一切都很好并且可以正常工作,我的意思是这是个不错的小功能...但是,我只想在用户插入或删除记录时登录数据库。
所以我需要命令名(插入或删除),表名,行ID ,以及该表中的另一个字段。
现在我看到的是这些方法中都有DBCommand。有一个名为Command Text ...的属性,它给出如下输出:
Intercepted on: ReaderExecuting :- IsAsync: False, Command Text: INSERT [dbo].[Student]([FirstName], [StandardId], [LastName])
VALUES (@0, NULL, NULL)
SELECT [StudentID], [RowVersion] FROM [dbo].[Student]
WHERE @@ROWCOUNT > 0 AND [StudentID] = scope_identity()
Intercepted on: ReaderExecuted :- IsAsync: False, Command Text: INSERT [dbo].[Student]([FirstName], [StandardId], [LastName])
VALUES (@0, NULL, NULL)
SELECT [StudentID], [RowVersion] FROM [dbo].[Student]
WHERE @@ROWCOUNT > 0 AND [StudentID] = scope_identity()
我的意思是可能会解析上述字符串中的所有内容...但是是否有一些更方便的方式来获取这些数据?
答案 0 :(得分:1)
仅具有EF的功能(未经测试的代码,但希望您能理解):
public void MyContext : DbContext
{
public override int SaveChanges() //not relevant if it is new, you can do it in another method.
{
foreach(var e in this.ChangeTracker.Entries())
{
if(e.State == EntityState.Added)
{
//log here
}
}
return base.SaveChanges();
}
}
对于原始查询,您需要解析器。
答案 1 :(得分:1)
作为一种选择,而不是拦截命令执行,您可以登录业务逻辑层:
public class ProductBusiness
{
ILogger logger;
//...
public void Create(Product p)
{
try
{
using (var db = new MyDbContext())
{
db.Products.Add(p);
db.SaveChanges();
logger.Log($"Create Product - {DateTime.Now} - Id:{p.Id}, Name:{p.Name}");
}
}
catch (Exception ex)
{
logger.Log($"Error - {DateTime.Now} - {ex.ToString()}");
throw;
}
}
//...
}