Меня попросили разработать аудит системы для моей работы.Система уже была завершена.Я думаю, что командный перехват EF 6 должен хорошо работать для моих целей.
Однако существуют ситуации, подобные этой, когда мы хотели бы знать, кто отправил запрос на отпуск, и мы хотели бы иметь возможность перехватить эту Вставкузапрос.
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
Регистрация DBCommandInterceptor в Global.asax:
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 и зарегистрировал его и т. Д. Я могу видеть, что некоторые другие запросы перехватываются, но, поскольку описанная выше ситуация такова, что хранимая процедура вызывается «извне», я не могу получить параметры.
Это простой пример.Не все хранимые процедуры, которые вызываются аналогичным образом в системе, настолько просты.
Как лучше всего изменить вышеуказанную ситуацию, чтобы мы могли применить перехват и, следовательно, аудит?