c# - ईएफ क्यों अनावश्यक नल-चेक के साथ एसक्यूएल प्रश्न उत्पन्न कर रहा है?



sql-server entity-framework (2)

UseDatabaseNullSemantics = true सेट करें;

यह मानता है कि दो ऑपरेंड की तुलना करते समय डेटाबेस नल सेमेन्टिक्स प्रदर्शित किए जाते हैं या नहीं, दोनों संभावित रूप से शून्य हैं। मूल मूल्य गलत है। उदाहरण के लिए (operand1 == operand2) का अनुवाद इस प्रकार किया जाएगा: (operand1 = operand2) यदि UseDatabaseNullSemantics क्रमशः सत्य है (((operand1 = operand2) और (नहीं (operand1 IS NULL या operand2 पूर्ण है)) या ((operand1 IS न्यूल) और (operand2 IS NULL))) यदि UseDatabaseNullSemantics गलत है।

https://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbcontextconfiguration.usedatabasenullsemantics(v=vs.113).aspx

public class MyContext : DbContext
{
    public MyContext()
    {
        this.Configuration.UseDatabaseNullSemantics = true;
    }
}

आप इस सेटिंग को अपने डीबीकॉन्टेक्स्ट इंस्टेंस में बाहरी रूप से नीचे दिए गए कोड उदाहरण के रूप में सेट कर सकते हैं, मेरे दृष्टिकोण से (देखें @GertArnold टिप्पणी), यह एप्लिकेशन बेहतर होगा, क्योंकि यह डिफ़ॉल्ट डेटाबेस व्यवहार या कॉन्फ़िगरेशन नहीं बदलेगा):

myDbContext.Configuration.UseDatabaseNullSemantics = true;

https://src-bin.com

स्ट्रिंग फ़ील्ड पर खोज करते समय मैं ईएफ के साथ भयानक प्रश्न बनाने के साथ एक मुद्दे पर आया। इसने आलसी प्रोग्रामर की शैली में एक प्रश्न प्रस्तुत किया जिसमें शून्य जांच शामिल है जो पूरे सूचकांक को स्कैन करने के लिए मजबूर करता है।

निम्नलिखित प्रश्नों पर विचार करें।

  1. प्रश्न 1

    var p1 = "x";
    var r1 = ctx.Set<E>().FirstOrDefault(
                            subject =>
                                p1.Equals(subject.StringField));
    
  2. प्रश्न 2

    const string p2 = "x";
    var r2 = ctx.Set<E>().FirstOrDefault(
                            subject =>
                                p2.Equals(subject.StringField));
    

प्रश्न 1 पैदा करता है

WHERE (('x' = [Extent2].[StringField]) OR (('x' IS NULL) AND ([Extent2].[StringField] IS NULL))) 

और 4 सेकंड में निष्पादित करता है

प्रश्न 2 पैदा करता है

WHERE (N'x' = [Extent2].[StringField]) 

और 2 मिलीसेकंड में निष्पादित करता है

क्या किसी को किसी भी काम के बारे में पता है? (कोई पैरामीटर एक कॉन्स नहीं हो सकता है क्योंकि यह उपयोगकर्ता इनपुट द्वारा दर्ज किया गया है लेकिन शून्य नहीं हो सकता है।)

एनबी प्रोफाइल करते समय, दोनों प्रश्नों को sp_executesql के साथ ईएफ द्वारा तैयार किया जाता है; कारण के रूप में अगर वे सिर्फ निष्पादित किए गए थे तो क्वेरी ऑप्टिमाइज़र OR 'x' IS NULL चेक को अस्वीकार कर देगा।


Answer #1

आप स्ट्रिंगफ़ील्ड प्रॉपर्टी पर [Required] जोड़कर इसे ठीक कर सकते हैं

public class Test
{
    [Key]
    public int Id { get; set; }
    [Required]
    public string Bar{ get; set; }
    public string Foo { get; set; }

}


 string p1 = "x";
 var query1 = new Context().Tests.Where(F => p1.Equals(F.Bar));

 var query2 = new Context().Tests.Where(F => p1.Equals(F.Foo));

यह क्वेरी 1 है

{चुनें [विस्तार 1]। [आईडी] एएस [आईडी], [विस्तार 1]। [बार] एएस [बार], [विस्तार 1]। [फू] एएस [फू] [डीबीओ] से। [टेस्ट] एएस [विस्तार 1] कहां @ p__linq__0 = [विस्तार 1]। [बार]}

और यह क्वेरी 2 है

{चुनें [विस्तार 1]। [आईडी] एएस [आईडी], [विस्तार 1]। [बार] एएस [बार], [विस्तार 1]। [फू] एएस [फू] [डीबीओ] से। [टेस्ट] एएस [विस्तार 1] कहां (@ p__linq__0 = [विस्तार 1]। [फू]) या ((@ p__linq__0 शून्य है) और ([विस्तार 1]। [बार 2] शून्य है)}}





entity-framework