2011-02-10 9 views
11

मैं एक मेज "परीक्षण" कहा जाता है, जो केवल 1 स्तंभ, "NullableInt" (नल पूर्णांक प्रकार)LINQ रिटर्न 0 परिणामों

रिकॉर्ड कर रहे हैं : 1, 2, अशक्त

int? nullableInt = null; 
var t = db.tests.Where(x => x.NullableInt == null).ToList(); // returns 1 record 
var t2 = db.tests.Where(x => x.NullableInt == nullableInt).ToList(); // returns 0 records 

किसी कारण से, t2 भी यद्यपि यह "nullableInt" चर, जो, अशक्त का अपना महत्व होता है सिर्फ टी की तरह है, जो "अशक्त"

के खिलाफ तुलना कर रहा है उपयोग कर रहा है 0 रिकॉर्ड देता है,

किसी भी मदद की सराहना की जाएगी!

उत्तर

2

प्रश्नों को इस तरह से बनाया जा सकता है:

var q = db.tests; 
if(nullableInt.HasValue) 
{ 
    q = q.Where(x => x.NullableInt == nullableInt.Value); 
} 
else 
{ 
    q = q.Where(x => x.NullableInt == null); 
} 
var t2 = q.ToList(); 
+0

+1 यह बेकार है, लेकिन यह एकमात्र तरीका है = ( – Francisco

+0

नीचे मेरा उत्तर देखें, यह ईएफ 6 में तय है और आप ईएफ 5 में एक फिक्स में ऑप्ट इन कर सकते हैं। –

6

हाँ - यह LINQ-to-SQL/Entity Framework में एक बग है। IS NULL प्रश्न केवल तभी उत्पन्न किए जाएंगे यदि आप क्वेरी में शून्य को हार्डकोड करते हैं, तो वर्तमान में शून्य होने पर एक चर के बजाय।

दूसरा क्वेरी

SELECT ....... 
WHERE NullableInt == @someParam 
WHERE @someParam is null. 

कहाँ पहले उचित IS NULLWHERE खंड में उत्पन्न होगा उत्पन्न होगा।

यदि आप LINQ-to-SQL का उपयोग कर रहे हैं, तो आप अपने प्रश्नों को कंसोल पर लॉग कर सकते हैं। अपने आप को देखने के लिए, और यदि आप ईएफ का उपयोग कर रहे हैं, तो ToTraceString() आपको एक ही जानकारी (या SQL सर्वर प्रोफाइलर)

+2

असल में मुझे नहीं लगता कि यह एक बग है क्योंकि दूसरी अभिव्यक्ति में 'nullableInt'' शून्य 'नहीं है, यहां तक ​​कि आप' nullableInt = null' के साथ अपना मान असाइन करते हैं (क्योंकि यह एक संरचना है, जिसका मान शून्य नहीं हो सकता है) । इस प्रकार ढांचा इसे अन्य structs (जैसे एक int) की तरह व्यवहार करता है। –

+2

@ डैनी, यह विभाजित बाल है। बग विनिर्देशन में हो सकता है, भले ही कोड ठीक वही करता है जो विनिर्देश कहता है कि इसे करना चाहिए। दूसरे शब्दों में, यहां की बग यह नहीं हो सकती है कि कोड कुछ गलत करने के लिए होता है, लेकिन किसी ने इस परिदृश्य पर विचार नहीं किया है। –

+1

बाल को वास्तव में विभाजित करना। कोई उचित कारण नहीं है कि ईएफ पार्सर को आईएस नल के अलावा कुछ और होने के लिए दूसरी क्वेरी क्यों उत्पन्न करनी चाहिए। और यह एमएस के साथ एक बग के रूप में लॉग किया गया है (बहुत अधिक वोट गिनती के साथ) हालांकि मेरे पास यह लिंक हाथ में नहीं है। –

0

वहाँ एक और समाधान है कि हमेशा एक छोटे से चेतावनी के साथ काम करेंगे, यद्यपि है:

int? nullableInt = null; 
var t2 = db.tests.Where(x => object.Equals(x.NullableInt, nullableInt)).ToList(); 

जब मान शून्य y है कहां उचित IS NULL क्वेरी मिल जाएगा, लेकिन जब इसकी रिक्त नहीं आप की तरह कुछ मिल जाएगा:

SELECT ... 
WHERE ([t0].[NullableInt] IS NOT NULL) AND ([t0].[NullableInt] = @p0) 

जाहिर है यह एक शर्त अतिरिक्त (स्रोत जिनमें से एक तरह से puzzling है) है। ऐसा कहा जा रहा है कि, SQL सर्वर के क्वेरी ऑप्टिमाइज़र को यह पता लगाना चाहिए कि, चूंकि @ p0 एक गैर-शून्य मान है, पहली स्थिति एक सुपरसेट है और जहां खंड को काट देगा।

+0

जो LINQ-to-SQL में काम कर सकता है (I haven इसका परीक्षण नहीं किया गया है) लेकिन यह निश्चित रूप से * नहीं * ईएफ 4 में काम करता है। यह अभी भी वही पुराना = @param उत्पन्न करता है जहां @param –

+0

आह पर सेट है, इसलिए उन्होंने इसे "निश्चित" किया है;)। हां, एल 2 एस में यह काम करता है। – mmix

0

चाहेंगे कर:

var t2 = db.tests.Where(x => x.NullableInt == nullableInt ?? null).ToList(); 

काम?

हालांकि यह पूरी तरह पागलपन जैसा लगता है।

+0

पागलपन वास्तव में, और नहीं, यह काम नहीं करता है। मैंने जेनरेट किए गए एसक्यूएल में डालने की कोशिश की, लेकिन यह असफल रहता है - मुझे लगता है कि यह किसी प्रकार के इंजेक्शन हमले के खिलाफ सुरक्षा कर रहा है –

2

tl; डॉ

आप EF6 में DbContext का उपयोग करते हैं यह तय हो गई है।

यदि आप ईएफ 5 (या ईएफ 6 में ऑब्जेक्ट कॉन्टेक्स्ट) का उपयोग कर रहे हैं तो आपको ऑब्जेक्ट कॉन्टेक्स्ट.कॉन्टेक्स्टऑप्शन। यूसीएसएएसएचआरपीएल कॉमपरिसनबैचर को सत्य पर सेट करने की आवश्यकता है। डीबीकॉन्टेक्स्ट पर ऐसा करने के लिए इसका उपयोग करें:

((IObjectContextAdapter)db).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = true; 

अधिक जानकारी

इस समस्या का मुख्य कारण कैसे डेटाबेस शून्य मान और कैसे सी # शून्य मान तुलना तुलना में एक अंतर है। क्योंकि आप सी # में अपनी क्वेरी लिखते हैं, आप सी # के अर्थशास्त्र का उपयोग करना चाहते हैं।

ईएफ 5 में हमने ऑब्जेक्टकॉन्टेक्स्ट.कॉन्टेक्स्टऑप्शन.यूसेस्सारपनुल कॉम्पर्सनबैवियर पेश किया, जिसने आपको डेटाबेस अर्थशास्त्र के बजाय सी # सेमेटिक्स का उपयोग करने का विकल्प चुना। डिफ़ॉल्ट गलत है (ताकि जब आप EF5 में अपग्रेड करते हैं तो मौजूदा प्रश्न जादूगर रूप से विभिन्न परिणामों को वापस नहीं करना शुरू करते हैं)। लेकिन आप इसे सत्य पर सेट कर सकते हैं और आपके प्रश्न पंक्तियों को वापस कर देंगे।

((IObjectContextAdapter)db).ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior = true; 

आप EF6 का उपयोग कर रहे हैं, तो यह पहले से ही सही पर DbContext पर सेट है तो आप बिल्कुल तैयार हैं:

आप EF5 में DbContext उपयोग कर रहे हैं आप इसे स्थापित करने के लिए ObjectContext को ड्रॉप डाउन करने की जरूरत है । हमने फैसला किया कि इस वजह से इतनी भ्रम पैदा हो रही है कि मौजूदा प्रश्नों पर संभावित प्रभाव डालने के लायक थे।

+0

धन्यवाद रोवन, यह बहुत उपयोगी था। – Eric

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^