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

और फिर एक वर्ग बनाया जो मेरे मूल डीबीकॉन्टेक्स्ट (ईएफ द्वारा जेनरेट किया गया) से निकला है और उपर्युक्त इंटरफ़ेस लागू करता है। फिर मैंने इस तरह दिखने के लिए अपना इंटरसेप्टर बदल दिया:

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 set सेट करें इससे पहले कि मैं कमांड निष्पादित करूं और बाद में इसे वापस असत्य पर सेट करूं।

इसे और अधिक आत्म-निहित बनाने के लिए, मैंने एक इंटरफ़ेस को इस तरह परिभाषित किया:

public interface IQueryHintContext
{
    string QueryHint { get; set; }
    bool ApplyHint { get; set; }
}

और इस तरह मेरे डीबी संदर्भ को बढ़ाया (आप निश्चित रूप से, ईएफ जेनरेट क्लास को भी विस्तारित करने के लिए आंशिक कक्षा का उपयोग कर सकते हैं):

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
}

यह शायद थोड़ा अधिक हो सकता है और इसे और विकसित किया जा सकता है (उदाहरण के लिए, एक स्ट्रिंग के बजाय उपलब्ध संकेतों के लिए एक एनम का उपयोग करना - या एक 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. समय भाग को अनदेखा करते हुए DATETIME और DATE की तुलना करें

  2. एकाधिक कॉलम पर चेक बाधा

  3. SQL सर्वर प्रदर्शन टॉप IO क्वेरी -2

  4. एक स्ट्रिंग के रूप में अल्पविराम सीमांकित सूची, टी-एसक्यूएल

  5. SQL LIKE क्लॉज में SqlParameter का उपयोग काम नहीं कर रहा है