gpt4 book ai didi

c# - Entity Framework 6,命令拦截和存储过程

转载 作者:太空狗 更新时间:2023-10-29 19:47:39 26 4
gpt4 key购买 nike

我被要求为工作中的系统开发审计。该系统已经完成。我认为 EF 6 的命令拦截应该很适合我的目的。

但是,在这种情况下,我们想知道是谁发送了请假请求,并且我们希望能够拦截此 Insert 查询。

using (DataContext context = new DataContext())
{
var result = context.CreateLeavePrerequest(
leaveRequest.LeaveType,
leaveRequest.StartDate,
leaveRequest.EndDate,
leaveRequest.NumberOfDays,
leaveRequest.EmployeeComment,
leaveRequest.HasSupportingDocumentation,
leaveRequest.ResourceTag,
leaveRequest.RemainingBalance,
leaveRequest.ApproverResourceTag,
leaveRequest.CapturerResourceTag,
leaveRequest.SupportingDocumentID,
ref id
);

那么存储过程就是:

CREATE PROCEDURE [dbo].[CreateLeavePrerequest]
(
@LeaveType VARCHAR(50) ,
@StartDate DATETIME ,
@EndDate DATETIME ,
@NumberOfDays DECIMAL(18, 5) ,
@EmployeeComment VARCHAR(512) ,
@SickNoteIndicator BIT ,
@ResourceTag INT,
@RemainingBalance DECIMAL,
@ApproverResourceTag INT,
@CapturerResourceTag INT,
@SupportingDocumentID INT,
@id INT = 0 OUT
)
AS
BEGIN
INSERT INTO [ESS PER LVE PreRequest]
( [Resource Tag] ,
[Leave Type] ,
[Start Date] ,
[End Date] ,
[No Of Days] ,
[Employee Comments] ,
[Sick Note Indicator],
[Status],
[Remaining Balance],
[Approver Resource Tag],
[Capturer Resource Tag],
[SupportingDocumentID]
)
SELECT @ResourceTag ,
@LeaveType ,
@StartDate ,
@EndDate ,
@NumberOfDays ,
@EmployeeComment ,
@SickNoteIndicator,
'Captured',
@RemainingBalance,
@ApproverResourceTag,
@CapturerResourceTag,
@SupportingDocumentID;
SELECT @id
END

更新:

CreateLeavePrerequest 实现如下:

public ISingleResult<CreateLeavePrerequestResult> CreateLeavePrerequest([global::System.Data.Linq.Mapping.ParameterAttribute(Name="LeaveType", DbType="VarChar(50)")] string leaveType, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="StartDate", DbType="DateTime")] System.Nullable<System.DateTime> startDate, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="EndDate", DbType="DateTime")] System.Nullable<System.DateTime> endDate, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="NumberOfDays", DbType="Decimal(18,5)")] System.Nullable<decimal> numberOfDays, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="EmployeeComment", DbType="VarChar(512)")] string employeeComment, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="SickNoteIndicator", DbType="Bit")] System.Nullable<bool> sickNoteIndicator, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="ResourceTag", DbType="Int")] System.Nullable<int> resourceTag, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="RemainingBalance", DbType="Decimal(18,0)")] System.Nullable<decimal> remainingBalance, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="ApproverResourceTag", DbType="Int")] System.Nullable<int> approverResourceTag, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="CapturerResourceTag", DbType="Int")] System.Nullable<int> capturerResourceTag, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="SupportingDocumentID", DbType="Int")] System.Nullable<int> supportingDocumentID, [global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] ref System.Nullable<int> id)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), leaveType, startDate, endDate, numberOfDays, employeeComment, sickNoteIndicator, resourceTag, remainingBalance, approverResourceTag, capturerResourceTag, supportingDocumentID, id);
id = ((System.Nullable<int>)(result.GetParameterValue(11)));
return ((ISingleResult<CreateLeavePrerequestResult>)(result.ReturnValue));
}

更新 2

Global.asax 中的 DBCommandInterceptor 注册:

 protected void Application_Start()
{
DbInterception.Add(new Auditor());
}

DBCommandInterceptor 实现:

我快速实现了这个,这样我就可以看到我是否可以拦截任何东西,所以它只是写入调试窗口。我已经能够拦截一些 Select 查询,但这不是我们想要审计的。

 public class Auditor : IDbCommandInterceptor
{
public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
CreateAuditMessage(command, interceptionContext);
}

public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
CreateAuditMessage(command, interceptionContext);
}

public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
CreateAuditMessage(command, interceptionContext);
}

public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
CreateAuditMessage(command, interceptionContext);
}

public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
CreateAuditMessage(command, interceptionContext);
}

public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
CreateAuditMessage(command, interceptionContext);
}

public static void CreateAuditMessage<T>(DbCommand command, DbCommandInterceptionContext<T> interceptionContext)
{
string message;

var parameters = new StringBuilder();
foreach (DbParameter param in command.Parameters)
{
parameters.AppendLine(param.ParameterName + " " + param.DbType + " = " + param.Value);
}

if (interceptionContext.Exception == null)
{
message = (parameters.ToString() + " " + command.CommandText);
}
else
{
message = (parameters.ToString() + command.CommandText + " " + interceptionContext.Exception);
}

Debug.WriteLine(message);
}
}

最近看了很多关于Entity Framework的资料,但不是很懂。我已经实现了 IDbCommandInterface 并注册了它等。我能够看到其他一些查询被拦截,但由于上述情况是存储过程被“外部”调用,我无法掌握参数。

这是一个简单的例子。并非系统中所有以类似方式调用的存储过程都这么简单。

改变上述情况的最佳方法是什么,以便我们可以应用拦截,从而应用审计?

最佳答案

您始终可以使用 Context Log 属性 拦截任何使用 DataContext 的数据库查询触发

您可以在 DataContext 类上定义构造函数,如下所示。

public class DataContext : DbContext, IDataContext
{

public DataContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
//NOTE: Instead of Debug.WriteLine, you can stroe it in DB.

}
.....
.....
.....
}

上下文日志属性记录了什么?

  • 用于所有不同类型命令的 SQL。例如:

    1- 查询、LINQ 查询、eSQL 查询和原始查询。

    2- 插入、更新和删除生成为SaveChanges 的一部分

    3- 诸如此类的关系加载查询延迟加载生成

  • 参数
  • 命令是否异步执行
  • 指示命令何时开始执行的时间戳
  • 命令是否成功完成,失败抛出一个异常,或者对于异步,被取消
  • 结果值的一些指示
  • 执行命令所花费的大概时间。笔记这是从发送命令到得到结果的时间对象回来。它不包括阅读结果的时间。

阅读更多关于。记录到不同的地方,结果记录,格式化等,你可以查看Logging and intercepting database operations

关于c# - Entity Framework 6,命令拦截和存储过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54668587/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com