在DBCommandInterceptor
中,我需要向sql中插入一些提示注释。为此,我试图通过静态DepartmentId
属性设置一些上下文信息。但是,这样做的问题是:由于使用TaskFactory.StartNew()
创建的每个任务同时使用了拦截器,因此这些任务可能会覆盖该信息。我该如何解决这个挑战?
public class MainClass {
private IDepartmentRepository _departmentRepository;
public void LoadDepartments() {
var departmentIds = new [] {1001, 1002};
foreach (var id in departmentService.GetDepartments())
{
TaskFactory.StartNew(() => GetDepartmentItems(id));
}
}
private void GetDepartmentItems(int departmentId) {
IList<int> departmentItemIds = _departmentRepository.GetDepartmentItemIds(); // Some complex logic
HintDbCommandInterceptor.DepartmentId = departmentId;
// This department ids are then put into memory cache
var departmentItems = _departmentRepository.GetDepartmentItems(departmentItemIds);
}
}
public class DepartmentRepository : IDepartmentRepository {
public IEnumerable<int> GetDepartmentItems(IList<int> departmentItemIds) {
var q = from di in DbContext.DepartmentItem where departmentItemIds.Contains(di.Id) select di;
return q.ToList();
}
}
public class HintDbCommandInterceptor : DbCommandInterceptor
{
public static int DepartmentId {get; set;}
public override void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> ctx)
{
DoIntercept(command, ctx);
base.NonQueryExecuted(command, ctx);
}
public override void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> ctx)
{
DoIntercept(command, ctx);
base.ScalarExecuted(command, ctx);
}
public override void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> ctx)
{
DoIntercept(command, ctx);
base.ReaderExecuted(command, ctx);
}
private string GetHint() {
return "/* Current-DepartmentId: ".DepartmentId." */";
}
public void DoIntercept(string commandType, DbCommand command, DbCommandInterceptionContext ctx)
{
try
{
command.CommandText = GetHint()." ".command.CommandText;
}
catch (Exception e)
{
}
}
}