Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Добавяне на намек за заявка при извикване на функция с таблична стойност

Попаднах на това:

https://entityframework.codeplex.com/wikipage?title=Interception

И изглежда, че можете да направите нещо подобно:

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 на global.asax.cs ):

DbInterception.Add(new HintInterceptor());

И ще ви позволи да промените CommandText . Единственият проблем е, че вече е прикачен за всеки читателска заявка, която може да е проблем, тъй като някои от тях може да бъдат отрицателно повлияни от този намек. Предполагам, че мога да направя нещо с контекста, за да разбера дали намекът е подходящ или не, или в по-лошия случай мога да проверя CommandText себе си.

Не изглежда най-елегантното или фино-зърнесто решение.

Редактиране :От 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; }
}

И разширих моя db контекст по този начин (можете, разбира се, просто да използвате частичен клас, за да разширите и генерирания от 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
}

Това може би е леко излишно и може да бъде доразвито (например, като се използва enum за налични съвети вместо низ - или подкласове recompile намек за заявка, така че не е необходимо да посочвате низа recompile всеки път и рискувам печатна грешка), но това реши непосредствения ми проблем.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Вложен оператор за избор в SQL Server

  2. Таблица за изчисление за вмъкване на липсващи дати между две дати? SQL

  3. Зависимости на SQL сървър

  4. Как да експортирам полето за изображение във файл?

  5. Групи за наличност на SQL Server AlwaysOn:Инсталация и конфигурация, част 2