【问题标题】:Can I modify the sql generated by Entity Framework before it's executed?我可以在执行之前修改Entity Framework生成的sql吗?
【发布时间】:2012-03-28 16:56:29
【问题描述】:

我有一个多租户数据库,根据查询的租户返回的行数大不相同。最近我们遇到了一个参数嗅探问题,其中针对一个租户 (TenantID = 1) 执行的实体框架 (EF) 查询比针对另一个租户 (TenantID = 2) 的相同查询花费的时间要长得多。我进行了一些研究并确定 EF 不支持查询提示(请参阅this question),这将允许我每次都强制重新编译查询。现在我想知道是否可以拦截 EF 生成的 Sql 查询并在执行之前手动附加“OPTION (OPTIMIZE FOR UNKNOWN)”。这可能吗? EF 是否可插入,以便我可以在生成的 Sql 执行之前对其进行修改?是否有任何示例说明如何执行此操作?

【问题讨论】:

    标签: sql-server entity-framework multi-tenant query-hints


    【解决方案1】:

    您是否尝试过解决该问题?您可以强制 EF 不使用参数,例如:

    var q = Context.Tenants.Where(t => t.TenantID == tenantId);
    

    ...将使用参数,但是:

    var r = Context.Tenants.Where(t => t.TenantID == 1);
    

    ...不会,我敢打赌:

    var s = Context.Tenants.Where("it.TenantID = 1");
    

    ...也不会。

    【讨论】:

    • 感谢您的建议。不幸的是,由于 sql 注入攻击的高风险,像您在此处所做的那样(尽管是间接地)即时构建 sql 查询被认为是不好的做法。参数化 sql 是将 sql 注入排除在应用程序之外的最佳和最简单的方法。
    • 嗯,这就是 EF 默认使用参数的原因。但是,如果您不清理输入,则注入只有风险。在您给出的特定情况下,仅允许整数输入将消除所有注入风险(尽管没有直接对象引用的风险,但参数也不会保护您免受这种影响......)。
    • 如果您正在使用 Fortify 扫描,那么在生成 SQL 之前知道您已经对输入进行了清理是不够聪明的。 ;)
    猜你喜欢
    • 2017-06-26
    • 2023-04-02
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    相关资源
    最近更新 更多