How can I specify an index hint in Entity Framework?

后端 未结 2 1738
慢半拍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(@"(?AS \[Extent\d+\](?! WITH \(*HINT*\)))", RegexOptions.Multiline | RegexOptions.IgnoreCase);
    
        [ThreadStatic] public static string HintValue;
    
        public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext 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 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 WithHint(this DbSet 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!

    提交回复
    热议问题