调用表值函数时添加查询提示

2023-12-03

我正在从实体框架调用表值函数,并且需要能够添加option (recompile)因为它选择的执行计划不是最佳的。在 SQL Server Management Studio 中运行查询,它看起来像这样:

select 
       * 
from dbo.fDE_myquery(0, 0, 3309, '7/1/2013', '7/1/2014', 0, 0)
option (recompile)

来自 EF,据我所知,无法添加该提示。 EF 部分看起来像:

var query = from f in ctx.fDE_myQuery(aBool, anotherBool, StartDate, 
            EndDate, someInt, moreBool)
            select f;

我看到这个问题:

如何控制实体框架中的参数嗅探和/或查询提示?

但它已经过时了,而且公认的解决方案并没有真正提供足够的信息来说明如何actually使用实体框架实施建议的解决方案(使用计划指南)。如果这是唯一的解决方案,那么如何让实体框架使用计划指南?


我遇到过这个:

https://entityframework.codeplex.com/wikipage?title=拦截

看来你可以做这样的事情:

public class HintInterceptor : DbCommandInterceptor
{
    public override void ReaderExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
    {
        command.CommandText += " option (recompile)";
        base.ReaderExecuting(command, interceptionContext);
    }
}

并像这样注册它(我是在Application_Start of global.asax.cs):

DbInterception.Add(new HintInterceptor());

它会让你改变CommandText。唯一的问题是它现在已附加到every读者查询这可能是一个问题,因为其中一些可能会受到该提示的负面影响。我猜我可以根据上下文做一些事情来确定提示是否合适,或者更糟糕的情况我可以检查CommandText itself.

看起来并不是最优雅或最细粒度的解决方案。

Edit: 来自interceptorContext,你可以得到DbContexts,所以我定义了一个如下所示的接口:

public interface IQueryHintContext
{
    string QueryHint { get; set; }
    bool ApplyHint { get; set; }
}

然后创建一个派生自我原来的DbContext(由EF生成)的类并实现上述接口。然后我将拦截器更改为如下所示:

public class HintInterceptor : DbCommandInterceptor
{
    public override void ReaderExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
    {
        if (interceptionContext.DbContexts.Any(db => db is Dal.IQueryHintContext))
        {
            var ctx = interceptionContext.DbContexts.First(db => db is Dal.IQueryHintContext) as Dal.IQueryHintContext;
            if (ctx.ApplyHint)
            {
                command.CommandText += string.Format(" option ({0})", ctx.QueryHint);
            }
        }
        base.ReaderExecuting(command, interceptionContext);
    }
}

现在要使用它,我使用派生类而不是原始类创建一个上下文,设置QueryHint无论我想要什么(recompile在这种情况下)并设置ApplyHint就在我执行命令之前,然后将其设置回 false。

为了使这一切更加独立,我最终定义了一个像这样的接口:

public interface IQueryHintContext
{
    string QueryHint { get; set; }
    bool ApplyHint { get; set; }
}

并像这样扩展我的数据库上下文(当然,您也可以只使用部分类来扩展 EF 生成的类):

public class MyEntities_Ext : MyEntities, IQueryHintContext
{
    public string QueryHint { get; set; }
    public bool ApplyHint { get; set; }
}

然后,为了使打开、关闭部分更容易处理,我定义了以下内容:

public class HintScope : IDisposable
{
    public IQueryHintContext Context { get; private set; }
    public void Dispose()
    {
        Context.ApplyHint = false;
    }

    public HintScope(IQueryHintContext context, string hint)
    {
        Context = context;
        Context.ApplyHint = true;
        Context.QueryHint = hint;
    }
}

现在要使用它,我可以这样做:

using (var ctx = new MyEntities_Ext()) 
{
    // any code that didn't need the query hint
    // ....
    // Now we want the query hint
    using (var qh = new HintScope(ctx, "recompile"))
    {
        // query that needs the recompile hint
    }
    // back to non-hint code
}

这可能有点矫枉过正,可以进一步开发(例如,使用枚举代替字符串来获取可用提示,或者子类化recompile查询提示,因此您无需指定字符串recompile每次都冒着打字错误的风险),但它解决了我眼前的问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调用表值函数时添加查询提示 的相关文章

随机推荐

  • 如何在不使用服务的情况下在子组件和父组件之间传递反应式表单数据

    当我们单击父级按钮时 我们希望使用来自父级的子级反应式表单数据 目前我们正在使用 viewchild 来获取子组件引用 我们正在获取所有静态数据 但没有获取表单填充的数据 parent component ts ViewChild Deta
  • Git 跟踪、未跟踪、暂存、索引的含义?

    有人可以澄清这些术语的含义吗 跟踪的文件是否是在某个时刻添加到舞台中的任何文件 索引 和 阶段 一样吗 是否跟踪所有暂存文件 但反之则不一定成立 即 曾经暂存并提交的文件 但不是要提交的当前阶段的一部分 我如何知道哪些文件被跟踪 我如何知道
  • 使用 volley 以 json 格式将数据发送到服务器

    您好 我正在以 json 格式将数据发布到服务器 但它在错误响应中返回齐射服务器错误 RequestQueue queue Volley newRequestQueue this JSONObject jobj new JSONObject
  • 自定义html标签——有更好的方法吗?

    我正在尝试完成一个浏览器插件 它将分析文本并以某种方式标记它 基本上 假设您在浏览时发现页面中的某处出现了此文本 p and then Tom Cruise devoured the planet p 该插件正在扫描文本并会找到 Tom C
  • JS:将数组减少为嵌套对象

    所以我有这个数组 var mapped 2016 October Monday object 2017 January Friday object 2017 January Wednesday object 2017 October Mon
  • 勾画出图中的区域

    我有两个 2D numpy 数组 尺寸相同 我正在使用 matplotlib 绘制它们 我将第一个数组绘制为灰度彩色图 第二个代表光圈 但它是不规则形状 一些像素被勾勒出轮廓 它是形成轮廓的一组水平和垂直线 我不知道如何要求它绘制第二个数组
  • 多边形三角剖分的相反是什么?

    完成 2D 三角测量后 一些三角形具有相同的颜色 我想重新组合它们以绘制类似颜色的图形路径 我发现 如果我只是一一绘制三角形 一些图形渲染器会显示三角形之间的接缝 至少在涉及抗锯齿和 或透明度的情况下 那么 如何获取一组 不重叠 三角形并生
  • 使用 ctop.xsl 的内容 mathml 到中缀表示法未获得所需格式

    我正在尝试从内容 mathml 中制作数学符号或中缀表达式 我正在提供帮助ctop xsl为了这 ctop xsl Refer 可以解析得到表达式如下
  • 互斥锁所有权队列顺序

    假设我有三个线程 它们都通过互斥体访问相同的互斥部分 让我给你举这个例子 第一个线程探测互斥体并首先获取其所有权 THREAD 1 TIME 2013 03 13 01 00 00 000Z WaitForSingleObject hMut
  • 如何使用 OpenCV 检测白色斑点

    I paint a picture to test 我想知道黑色圆圈中有多少斑点以及每个斑点的大小是多少 所有斑点都是白色的 For example in this case I have 12 spots 我知道如何找到白色像素 并且很容
  • 获取TCL中执行代码的行号

    如何打印执行TCL脚本的行号 usr bin tclsh set a 100 set b 200 set c expr a b puts info script it will display the script name which i
  • 如何将静态部分添加到javapoet中的java类中

    有没有办法使用javapoet库将静态代码块添加到java类中 static whatever code is needed for initialization goes here Use TypeSpec Builder addStat
  • 为什么没有安装tensorflow?

    我无法安装张量流 显示此错误 错误 找不到满足张量流要求的版本 来自版本 无 错误 找不到张量流的匹配分布 我安装了Python 3 11 但再次收到相同的错误消息 我用谷歌搜索了这个错误 并尝试了一些向其他人建议的方法 但没有任何效果 包
  • 使工作簿保存中特定工作表的字段成为必填字段

    我在 Excel 中使用宏来使 Excel 工作簿中的字段成为必填字段 但是 问题是工作簿包含多个工作表 并且宏适用于所有工作表 有没有办法定位工作簿中的特定工作表 下面是我正在使用的代码 Private Sub Workbook Befo
  • SwiftUI 如何设置下划线与文本之间的间距?

    设置下划线的代码 我想让文字和下划线之间的间距变大 Text underline text underline 下划线是一种字体功能 您只需在需要的地方画线即可进行自定义 var body some View HStack Text Bef
  • 为什么不能用 C 语言编写 scanf("%.2lf", &a) ?

    我的朋友刚刚开始学习编程 他向我展示了他的代码并询问为什么它返回一些奇怪的数字 我看了一下 发现他用的是scanf 2lf a 接受输入 并按照习惯 我尝试将其更改为正常 然后他问我为什么它有一些奇怪的输出 谷歌搜索后我仍然没有找到答案 谁
  • EmailProperty 与 StringProperty 有何不同?

    如何EmailProperty与 不同StringProperty 考虑这两个例子 example 1 store an e mail address in an EmailProperty class MyModel db Model e
  • 如何在android中的一个布局上显示一半按钮,在另一个布局上显示一半按钮?

    我想设计一个如下图所示的布局 我尝试使用相对布局来做到这一点 但我没有想出解决方案 对于所有设备屏幕 它应该位于相同的位置 我怎样才能实现它 我尝试了这段代码
  • 如何在画布上绘制位图,同时尊重位图的 alpha 值?

    背景 我有一个主位图 我需要在其上绘制其他位图 主位图有一些半透明像素 具有 Alpha 通道变量值的像素 因此在其上绘制的其他位图应与其合并 而不是完全覆盖颜色 问题 我如何设置画布以在主位图上绘制相对于半透明像素的位图 注意 alpha
  • 调用表值函数时添加查询提示

    我正在从实体框架调用表值函数 并且需要能够添加option recompile 因为它选择的执行计划不是最佳的 在 SQL Server Management Studio 中运行查询 它看起来像这样 select from dbo fDE