- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我们正在使用 DiagnosticListeners
来修改 EF Core 生成的 SQL 命令文本。问题是我们的监听器需要根据通过 HttpRequests 进入我们的 Api 的一些用户特定数据来修改 SQL 命令。我们当前的解决方案非常老套,将来可能会导致问题。每次创建 DbContext
时,我们都会注册一个新的监听器:
public class MyContext : DbContext
{
private readonly HReCommandAdapter _adapter;
public MyContext(DbContextOptions options) : base(options)
{
_adapter = new DbCommandAdapter();
var listener = this.GetService<DiagnosticSource>();
(listener as DiagnosticListener).SubscribeWithAdapter(_adapter);
}
public override void Dispose()
{
_adapter.Dispose();
base.Dispose();
}
//DbSets and stuff
}
简化的监听器代码如下所示:
public class DbCommandAdapter : IDisposable
{
private bool _hasExecuted = false;
private Guid? _lastExecId = null;
[DiagnosticName("Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting")]
public void OnCommandExecuting(DbCommand command, DbCommandMethod executeMethod, Guid commandId, Guid connectionId, bool async, DateTimeOffset startTime)
{
if (!_lastExecId.HasValue)
_lastExecId = connectionId;
if (_lastExecId != connectionId)
return;
//We are modifying command text here
}
[DiagnosticName("Microsoft.EntityFrameworkCore.Database.Command.CommandExecuted")]
public void OnCommandExecuted(object result, bool async)
{
}
[DiagnosticName("Microsoft.EntityFrameworkCore.Database.Command.CommandError")]
public void OnCommandError(Exception exception, bool async)
{
}
public void Dispose() { //No code in here }
}
如您所见,我们当前的方法是使用每次创建 DbContext
时都不同的 connectionId
。之所以采用这种 hacky 方法,是因为即使每次处理 HttpRequest
时都会调用 DbContext.Dispose()
,也不会释放监听器实例。因此,connectionId
基本上允许在监听器和给定的 DbContext
实例之间产生 1:1 映射的错觉。
但是发生的是,在 API 的整个生命周期中,监听器实例的数量不断堆积,并且实例消失的唯一时间是应用程序池停止或回收时。
是否有可能以某种方式处理这些监听器实例以及如何处理?我也愿意采用不同的方法来修改 SQL 命令(诊断监听器是我们为 EF Core 找到的唯一可行的方法)。
编辑:我只修改 SELECT
命令。我省略了细节,但是 DbCommandAdapter
创建时带有用户特定的前缀,该前缀因尝试访问 API 的用户而异。
例如,如果查询是:
SELECT FIELD1, FIELD2 FROM EMPLOYEES
并且用户特定前缀是USER_SOMENUMBER
,然后修改后的查询结束:
从 USER_SOMENUMBER_EMPLOYEES 中选择 FIELD1、FIELD2
我知道这很脆弱,但我们保证我们更改的表名的架构是相同的,这不是问题。
最佳答案
如果您不能处理监听器,为什么不将它们集中起来并重用它们呢?当配置或构建成本高昂时,池化是一种很好的软件模式。防止无限增长也是一种合理的用法。
以下仅为伪代码。它需要知道适配器事务何时完成,以便它可以标记为可用和重用。它还假定更新后的 myDbContext 将具有执行工作所需的内容。
public static class DbCommandAdapterPool
{
private static ConcurrentBag<DbCommandAdapter> _pool = new ConcurrentBag<DbCommandAdapter>();
public static DbCommandAdapter SubscribeAdapter(MyContext context)
{
var adapter = _pool.FirstOrDefault(a => a.IsAvailable);
if (adapter == null)
{
adapter = new DbCommandAdapter(context);
_pool.Add(adapter);
}
else adapter.Reuse(context);
return adapter;
}
}
public class MyContext : DbContext
{
private readonly HReCommandAdapter _adapter;
public MyContext(DbContextOptions options) : base(options)
{
//_adapter = new DbCommandAdapter();
//var listener = this.GetService<DiagnosticSource>();
//(listener as DiagnosticListener).SubscribeWithAdapter(_adapter);
DbCommandAdapterPool.SubscribeAdapter(this);
}
public override void Dispose()
{
_adapter.Dispose();
base.Dispose();
}
//DbSets and stuff
}
public class DbCommandAdapter : IDisposable
{
private bool _hasExecuted = false;
private Guid? _lastExecId = null;
private MyContext _context;
private DiagnosticListener _listener;//added for correlation
public bool IsAvailable { get; } = false;//Not sure what constitutes a complete transaction.
public DbCommandAdapter(MyContext context)
{
this._context = context;
this._listener = context.GetService<DiagnosticSource>();
}
...
public void Reuse(MyContext context)
{
this.IsAvailable = false;
this._context = context;
}
}
注意:我自己还没有尝试过。 Ivan Stoev 建议将对 ICurrentDbContext 的依赖注入(inject)到 CustomSqlServerQuerySqlGeneratorFactory,然后在 CustomSqlServerQuerySqlGenerator 中可用。参见:Ef-Core - What regex can I use to replace table names with nolock ones in Db Interceptor
关于c# - 查询拦截 - 处理诊断监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54038867/
当我在一台机器上启动我的应用程序时,它立即退出说它已经“停止工作”。在事件日志中,我看到 MissingMethodException 是原因。没有显示异常对话框,并且在事件日志详细信息中我看不到任何
我正在从 Windows Phone 8 模拟器调用 Azure 移动服务。有时我会收到没有 InnerException 属性的 MobileServiceInvalidOperationExcep
我正在创建一个 Web 客户端,用于使用 ACS Calling SDK 加入 Teams session 。我在加载诊断 API 时遇到问题。 Microsoft 提供了此页面: https://l
知道为什么我的应用程序被杀死吗?我是该节点的唯一用户。 我的历史记录服务器也没有显示任何内容。我如何进一步追踪并了解是谁杀死了它,以及为什么以及如何修复它? ubuntu@anmol-vm1-new:
我正在创建一个 Web 客户端,用于使用 ACS Calling SDK 加入 Teams session 。我在加载诊断 API 时遇到问题。 Microsoft 提供了此页面: https://l
我正在寻找一种从 Windows Azure 中的性能计数器获取原始数据的方法 使用诊断 API。 到目前为止,我注意到我可以从已知的计数器中配置一个计数器 并设置该计数器的采样率。 诊断配置中配置的
我在将 WebRole(WCF 服务)部署到 Azure 时遇到问题。我的 WebRole 持续显示忙碌状态至少 30 分钟,直到我中止它。我通过 Visual Studio 2010 进行部署。我正
Clang has several kinds of diagnostics ,其中三种主要是错误、警告和注释。 注释通常伴随着某些警告和错误,例如重复定义: error: conflicting t
调试由于 Win32 生产过程中的死锁而导致的明显挂起的步骤和技术是什么。我听说 WinDbg 可用于此目的,但您能否提供有关如何实现此目的的明确提示? 最佳答案 此 post应该让您开始使用各种选项
我有一个在 Azure 上运行的应用程序,它会记录(实际上是跟踪)到 Azure 诊断存储。我正在寻找一个可以用来分析这些日志的好工具。 我知道可以使用 Visual Studio 中的服务器资源管理
我在当前项目中使用 Bazel 经历了很长的“干净构建”时间。 我们推荐的诊断步骤是什么? 最佳答案 尝试使用 --profile 分析您的构建 语法为 bazel build --profile f
我在解释 gcc (4.8.2) 警告和错误时遇到问题。更准确地说,很难分辨一个问题在哪里结束,另一个问题从哪里开始。我只能通过控制台访问构建机器,因此不能选择使用 IDE。 我真的需要能够快速区分个
我想为我的 azure 云服务启用 azure 诊断,但我有点困惑。 我读了这篇文章:https://learn.microsoft.com/en-us/azure/cloud-services/cl
我想我这里有个卷曲的地方...我有一个WinForms应用程序,当它作为x64进程运行时,它每小时大约会定期崩溃。我怀疑这是由于堆栈损坏引起的,并且想知道是否有人看到过类似的问题,或者是否有诊断和检测
我正在研究 Azure Web 角色的性能改进,并想知道在发布/部署到生产站点时是否应保留诊断。 This article说要禁用它,但其中一条评论说您会丢失关键数据。 最佳答案 您绝对应该启用它。一
我的解决方案中有多个 Web 和辅助角色,但我还有一个在 Azure 托管 VM 上运行的非 Azure 应用程序。该应用程序连接到 Azure 存储以执行各种操作,例如读取和写入 blob 和队列,
我仍在努力理清思路 Azure Service Fabric Stateful Actors 。因此,我的(当前)问题最好放入这样的示例中: 我有一个帮助台系统,其中每张票证都是一个有状态的参与者。参
CUDA 到处都有大量文档和指南,但我找不到任何形式的说明来指导如何诊断编译但收到神秘、模糊错误消息(例如“未指定启动”)的内核“这些 block /网格结构有意义吗?”等等 我可以以某种方式拦截cu
我没有找到太多解决 azure 事件网格中事件丢失场景的方法。 因此我提出与以下场景相关的问题: 我们的代码将事件发布到域。 事件将传送到订阅中配置的网络 Hook 。 这在一段时间内有效。 消费者(
这个问题有点宽泛,但我觉得没有一个地方可以帮助系统地诊断 Elasticsearch 问题。广泛的类别可能是: 客户 查询错误 查询结果不正确 无法解释的行为 服务器 设置问题 性能问题 严重错误 无
我是一名优秀的程序员,十分优秀!