How can I specify an index hint in Entity Framework?

后端 未结 2 1735
慢半拍i
慢半拍i 2020-12-15 08:01

sql

select * from table1 with(index=IX_table1_1)

Linq to sql using ado.net entity would like to write the above code. I could not find en

相关标签:
2条回答
  • 2020-12-15 08:42

    Solution is simple. Let's add an Interceptor !!!

        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;
        }
    }
    

    The regex could be better, i know. Let's register our Interceptor in Config class

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

    Let's make nice Hint Extension for 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;
        }
    }
    

    How to use ?

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

    Modifications are welcomed!

    0 讨论(0)
  • 2020-12-15 08:43

    Neither L2S nor EF will provide direct support for SQL as bespoke as that (index hints, etc), although with L2S you can achieve it via ExecuteQuery<T>(...) (which takes raw TSQL). If you need that level of control, consider either stored procedures or an alternative ORM.

    One problem in particular here is that query hints are pretty platform specific, but EF tries to be platform-neutral.

    0 讨论(0)
提交回复
热议问题