Как я могу указать подсказку индекса в Entity Framework? - PullRequest
9 голосов
/ 07 ноября 2011

1001 * SQL * select * from table1 with(index=IX_table1_1) Linq to sql, используя объект ado.net, хотел бы написать приведенный выше код. Я не мог найти сущность, в частности, использование индекса. * 1006 LINQ * var querysample = from a in db.table1 select a;

Ответы [ 2 ]

11 голосов
/ 30 января 2016

Решение простое. Давайте добавим перехватчик !!!

    public class HintInterceptor : DbCommandInterceptor
{
    private static readonly Regex _tableAliasRegex = new Regex(@"(?<tableAlias>AS \[Extent\d+\](?! WITH \(*HINT*\)))", RegexOptions.Multiline | RegexOptions.IgnoreCase);

    [ThreadStatic] public static string HintValue;

    public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        if (!String.IsNullOrWhiteSpace(HintValue))
        {
            command.CommandText = _tableAliasRegex.Replace(command.CommandText, "${tableAlias} WITH (*HINT*)");
            command.CommandText = command.CommandText.Replace("*HINT*", HintValue);
        }

        HintValue = String.Empty;
    }

    public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        if (!String.IsNullOrWhiteSpace(HintValue))
        {
            command.CommandText = _tableAliasRegex.Replace(command.CommandText, "${tableAlias} WITH (*HINT*)");
            command.CommandText = command.CommandText.Replace("*HINT*", HintValue);
        }

        HintValue = String.Empty;
    }
}

Регулярное выражение могло бы быть лучше, я знаю. Зарегистрируем наш перехватчик в классе Config

public class PbsContextConfig : DbConfiguration
{
    public PbsContextConfig()
    {
        this.AddInterceptor(new HintInterceptor());
    }
}

Давайте сделаем красивое расширение Hint для DbSet

public static class HintExtension
{
    public static DbSet<T> WithHint<T>(this DbSet<T> set, string hint) where T : class
    {
        HintInterceptor.HintValue = hint;
        return set;
    }
}

Как пользоваться?

context.Persons.WithHint("INDEX(XI_DOWNTIME_LOCK)").Where( x => x.ID == ....

Модификации приветствуются!

3 голосов
/ 07 ноября 2011

Ни L2S, ни EF не будут предоставлять такую ​​прямую поддержку SQL, как эта (указатели индекса и т. Д.), Хотя с помощью L2S вы можете достичь этого с помощью ExecuteQuery<T>(...) (который использует необработанный TSQL). Если вам нужен такой уровень контроля, рассмотрите хранимые процедуры или альтернативный ORM.

Одна из проблем, в частности, здесь заключается в том, что подсказки к запросу довольно специфичны для платформы, но EF пытается быть нейтральным к платформе.

...