我使用的是Entity Framework 6,并希望在对数据进行任何修改之前设置CONTEXT_INFO
,因此我的审核触发器可以记录哪些用户进行了修改。看来应该可以使用IDbCommandInterceptor
来更改将要执行的CommandText
,类似下面的代码。但是如果DbCommand.CommandType == CommandType.StoredProcedure
那么它不是这样的,因为它期望CommandText
将只是过程名称,如果我用它作为前缀,则会抛出错误我的额外SQL。
public class SetContextInterceptor : IDbCommandInterceptor
{
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
command.CommandText = GetSqlForSetContextInfo() + command.CommandText;
}
// ... other interface methods similar
private string GetSqlForSetContextInfo()
{
var currentUsername = Thread.CurrentPrincipal != null && Thread.CurrentPrincipal.Identity != null
? Thread.CurrentPrincipal.Identity.Name
: null;
if (String.IsNullOrEmpty(currentUsername))
{
return "";
}
return "EXEC usp_setUserContext '" + currentUsername.Replace('\'', ' ') + "'; ";
}
}
特别是在这种情况下CommandText
中的参数不存在(即CommandText只包含存储过程名称),所以我不想进入做字符串的混乱业务操纵参数。有一种简单的方法来处理这种情况吗?
这里有一些关于用CONTEXT_INFO
实现类似事情的其他文章。看起来这个主题有很多变化,但没有达成一致的方式,许多技术都是在EF6之前,所以没有IDbCommandInterceptor
选项。
how can i set the context_info sql statement from Devforce IdeaBlade app
http://blogs.msmvps.com/p3net/2013/09/13/entity-framework-and-user-context/
http://davecallan.com/passing-userid-delete-trigger-entity-framework
更新
我猜测因为it's not possible to get the 'SQL' that's executed当CommandType = StoredProcedure时,它无法操纵它。我遇到的选项(对于我想设置CONTEXT_INFO的场景)是抓取command.Connection
并执行单独的命令来设置CONTEXT_INFO。我不确定它的效果如何,例如如果连接尚未打开,那么我必须自己打开它。
From .NET can I get the full SQL string generated by a SqlCommand object (with SQL Parameters)?
答案 0 :(得分:0)
根据我上面的更新,我认为这是不可能的。