2009-11-17 18 views
6

मेरे पास SQL ​​क्वेरी के लिए एक बहुत जटिल लिंक है जो एक Microsoft SQL सर्वर डेटाबेस से परिणाम सेट देता है। क्वेरी के समान वाक्य रचना का उपयोग कर बनाया जाता है:लिंक क्वेरी रिटर्न गलत परिणाम सेट करें

Dim db as MyDataContext = MyGetDataContextHelper() 
Dim qry = From rslt in db.MyView Select ColumnList 

If userParam1 IsNot Nothing Then 
    qry = qry.Where(lambda for the filter) 
End If 

etc.... 

Return qry.ToList() 

वहाँ प्रश्न के कई उपयोगकर्ता द्वारा निर्दिष्ट फिल्टर कर रहे हैं, एक है कि एक भौगोलिक त्रिज्या खोज करता है भी शामिल है।

यहां समस्या है। मेरे पास अंत में "ToList" कॉल पर एक ब्रेक सेट है। जब ब्रेक मारा जाता है तो मैं जेनरेट किए गए SQL कथन को देखने के लिए लिंक से SQL डीबग विजुअलाइज़र का उपयोग करता हूं। मैं उस जटिल SQL कथन को एक SQL सर्वर प्रबंधन स्टूडियो क्वेरी विंडो में कॉपी करता हूं और मुझे अपने इच्छित डेटाबेस को ठीक करने के लिए इसे अपने डेटाबेस के विरुद्ध निष्पादित करता हूं। तो जेनरेट एसक्यूएल वांछित परिणाम उत्पन्न करने के लिए प्रतीत होता है। हालांकि, जब मैं क्वेरी ऑब्जेक्ट की "ToList" विधि निष्पादित करता हूं तो लौटाई गई सूची में कम पंक्तियां और कुछ अलग पंक्तियां होती हैं। मैंने डेटाकॉन्टेक्स्ट लॉग प्रॉपर्टी को एक ही फाइल के साथ फ़ाइल में लिखने का भी प्रयास किया है। क्वेरी SQL प्रबंधन स्टूडियो में सही परिणाम सेट उत्पन्न करती है, लेकिन ToList विधि से गलत परिणाम।

यह कैसे हो सकता है? यदि जेनरेट किया गया एसक्यूएल बस SQL ​​सर्वर से कनेक्शन पर पारित किया गया है, तो क्या यह SQL सर्वर प्रबंधन स्टूडियो में वास्तव में परिणाम सेट उत्पन्न नहीं करेगा? मुझे लगता है कि मैं लिंक से एसक्यूएल तंत्र के बारे में कुछ गलत समझ रहा हूं, यानी कि यह सिर्फ SQL सर्वर के लिए एक पासथ्रू नहीं है। क्या वो सही है?

संपादित करें: नीचे कोई अनुरोध के अनुसार, यहां एसक्यूएल कि Linq से उत्पन्न होता है, संक्षिप्तता के लिए निकाले गए परिणाम स्तंभों से अधिकांश के साथ का एक बहुत संक्षिप्त संस्करण है। यह एसक्यूएल प्रबंधन स्टूडियो में सही परिणाम उत्पन्न करता है, लेकिन परिणाम मेरे आवेदन में वापस आ गया है।

SELECT [t3].[Id] 
FROM (
    SELECT DISTINCT [t1].[Id] 
    FROM (
     SELECT [t0].[Id], [t0].[ItemDate] 
     FROM [dbo].[MySearchView] AS [t0] 
     ) AS [t1] 
    WHERE (EXISTS(
     SELECT NULL AS [EMPTY] 
     FROM [dbo].[ZipCoverage] AS [t2] 
     WHERE ([t2].[Id] = [t1].[Id]) 
     AND ([t2].[Latitude] >= (41.09046 - (0.5))) 
     AND ([t2].[Latitude] <= (41.09046 + (0.5))) 
     AND ([t2].[Longitude] >= (-73.43106 - (0.5))) 
     AND ([t2].[Longitude] <= (-73.43106 + (0.5))) 
     AND (ABS(3956.08833132861 * 2 * ATN2(SQRT(POWER(SIN((((CONVERT(Float,CONVERT(Float,0.0174532925199433))) * [t2].[Latitude]) - 0.717163818159029)/(CONVERT(Float,2))), 2) + (COS(0.717163818159029) * COS((CONVERT(Float,CONVERT(Float,0.0174532925199433))) * [t2].[Latitude]) * POWER(SIN((((CONVERT(Float,CONVERT(Float,0.0174532925199433))) * [t2].[Longitude]) - -1.28161377022951)/(CONVERT(Float,2))), 2))), SQRT((1 - POWER(SIN((((CONVERT(Float,CONVERT(Float,0.0174532925199433))) * [t2].[Latitude]) - 0.717163818159029)/(CONVERT(Float,2))), 2)) + (COS(0.717163818159029) * COS((CONVERT(Float,CONVERT(Float,0.0174532925199433))) * [t2].[Latitude]) * POWER(SIN(((CONVERT(Float,CONVERT(Float,0.0174532925199433))) * [t2].[Longitude])/(CONVERT(Float,2))), 2))))) <= 5))) 
     AND ([t1].[ItemDate] <= '11/17/2009 8:12:42 PM') 
    ) AS [t3] 

अद्यतन 2009-11-17 इस मामले से संबंधित एमएस संपर्क करने में सक्षम था। एक नमूना आवेदन बनाया जो मैंने उनके समर्थन प्रतिनिधि को प्रस्तुत किया था। उन्होंने इस मुद्दे को दोहराया है और शोध कर रहे हैं। जब मुझे प्रतिक्रिया मिलती है तो उत्तर पोस्ट करेंगे।

अद्यतन 2009-12-21 अंततः माइक्रोसॉफ्ट से मदद के साथ सही उत्तर पर पहुंचे। स्पष्टीकरण के लिए कृपया नीचे अपना स्वीकृत उत्तर देखें।

+1

क्या आप अपनी वास्तविक LINQ क्वेरी पोस्ट कर सकते हैं? आपने कहा कि यह बहुत जटिल था। यह देखते हुए कि बाकी सब कुछ क्रम में प्रतीत होता है, शेष विकल्प यह है कि आपकी LINQ क्वेरी में रनटाइम-केवल प्रोसेसिंग होती है जो अनुवादक एसक्यूएल में नहीं जा सका। – jrista

+0

मैंने नीचे दिए गए मेरे उत्तर पर आपकी टिप्पणी का जवाब दिया। –

+0

क्या कोई ऑर्डर नहीं है? हम कितने पंक्तियों के बारे में बात कर रहे हैं, और आप कैसे मान्य हैं कि परिणाम अलग हैं? क्या यह संभव है कि आदेश अलग है और इसे परिणाम की तरह दिखाना अलग है? –

उत्तर

2

ठीक है, माइक्रोसॉफ्ट से बहुत उपयोगी समर्थन प्रतिनिधि के साथ कुछ और आगे के बाद, हम अंततः समस्या के स्रोत पर पहुंचे। और दुर्भाग्य से मैंने दृढ़ संकल्प करने के लिए एसओ पर किसी के लिए अपनी मूल पोस्ट में पर्याप्त जानकारी नहीं दी है, इसलिए उस संबंध में मेरी माफ़ी।

यहाँ मुद्दा है - कोड है कि प्रश्न में LINQ क्वेरी का निर्माण के हिस्से के रूप में, मैं तो जैसे एक नेट चर की घोषणा की:

Dim RadCvtFactor As Decimal = Math.PI/180 

ऐसा नहीं है कि पता चला है जब इस पैरामीटर घोषणा SQL करने के लिए पारित हो जाता है , जैसा LINQ लॉग फ़ाइल में प्रमाणित है, डेसिमल (2 9, 4) है। घोषणा पर पैमाने के मूल्य के कारण आरडीबीएमएस के माध्यम से एक अवैध मूल्य पारित किया जाता है, जिसके परिणामस्वरूप क्वेरी परिणामों में अजीब अंतर होता है।

एक एकल मान के रूप में नेट चर की घोषणा, इसलिए जैसे:

Dim RadCvtFactor As Single = Math.PI/180 

पूरी तरह से समस्या को सही।

माइक्रोसॉफ्ट प्रतिनिधि ने स्वीकार किया कि यह पैरामीटर रूपांतरण "संभावित समस्या" हो सकता है और उत्पाद टीम से परामर्श लेगा।

उत्तर सबमिट करने वाले सभी लोगों के लिए धन्यवाद।

1

एक चीज जो तुरंत दिमाग में आती है वह एक अनुमति मुद्दा है। क्या यह संभव है कि प्रोग्राम और मैन्युअल रूप से निष्पादित क्वेरी अलग-अलग प्रमाण-पत्रों के तहत चल रही है और इसलिए डेटाबेस में अलग-अलग पहुंच स्तर हैं? यह क्वेरी के परिणामों को प्रभावित कर सकता है।

+0

हालांकि यह संभवतः गायब पंक्तियों को समझा सकता है, मुझे लगता है कि यह बहुत ही असंभव है कि एक ही पंक्ति दो संदर्भों में अलग-अलग दिखाई देगी, जब तक कि क्वेरी जानबूझकर उपयोगकर्ता नाम के आधार पर CASE अभिव्यक्तियों के साथ तैयार नहीं की जाती। मुझे लगता है कि यह सिर्फ एक चयन क्वेरी है और संग्रहीत प्रक्रिया कॉल नहीं है (जहां बॉब मैक के लिए ऐसा तर्क अदृश्य हो सकता है)। –

+0

हां, यह केवल एक चयन क्वेरी है, संग्रहित प्रो कॉल नहीं। –

+0

मैंने प्रोग्राम के क्रेडेंशियल का उपयोग कर SQL सर्वर प्रबंधन स्टूडियो में लॉग इन किया और क्वेरी को आजमाया। मुझे सही परिणाम मिल गए हैं इसलिए अनुमतियां प्रतीत नहीं होती हैं। हालांकि धन्यवाद। –

1

मैं आपके डेटा कॉन्टेक्स्ट को देखकर शुरू करूंगा। यदि आपका डेटा कॉन्टेक्स्ट SQL सर्वर से अद्यतन नहीं किया जा रहा है, तो आप तालिका के पुराने संस्करण को वापस कर रहे हैं।

डेटाकॉन्टेक्स्ट डेटाबेस बनाते समय डेटाबेस की स्थिति बनाए रखता है। आप संचालन के प्रत्येक सेट के लिए एक नया संदर्भ उपयोग करना चाहते हैं।

+0

यह एक अच्छा विचार है, शायद एक पंक्ति के खिलाफ एक बहुत ही सरल क्वेरी के साथ प्रयास करें। डेटाबेस में पंक्ति अद्यतन करें और देखें कि क्या लिंकक पकड़ता है या नहीं। –

+0

जब मैंने यह उत्तर पढ़ा तो मैंने सोचा कि यह समस्या थी, लेकिन मैंने डीबीएमएल फ़ाइल में प्रासंगिक तालिकाओं और विचारों को बिना किसी खुशी के अपडेट किया। –

+0

डीबीएमएल नहीं, बल्कि वास्तविक डेटाकॉन्टेक्स्ट। जब भी आप एक नया ऑपरेशन करते हैं तो आपको Dim = d को संदर्भ = new MyDbContext() के रूप में करना चाहिए। यदि MyGetDataContextHelper() कॉल के बीच एक संदर्भ का पुन: उपयोग करता है, तो यह डेटाबेस से सबसे ताज़ी तालिका को पकड़ नहीं पाएगा। –

1

एक और संभावना अलगाव स्तर और डेटा की प्रकृति है। क्या आप अक्षय पढ़ने या लिंक के तहत अनन्य या स्नैपशॉट पढ़ रहे हैं? एसएसएमएस का उपयोग करते समय क्या? स्पष्ट रूप से यदि डेटा चारों ओर घूम रहा है तो एक ढीला अलगाव स्तर आपको पंक्तियों को छोड़ने, पंक्तियों के पुराने संस्करण को देखने,

इसके अलावा, क्या आप हमें " बहुत जटिल सवाल "जैसा दिखता है? आपको अपने असली टेबल नामों का उपयोग करने की ज़रूरत नहीं है।

+0

आपके अनुरोध के अनुसार, मैंने लिंक से जेनरेट की गई क्वेरी का एक संघीय संस्करण पोस्ट किया। मुझे यकीन नहीं है कि मैं रीपेटाबल रीड का उपयोग कैसे करूँगा या पढ़ा जाएगा, क्या आप विस्तृत कर सकते हैं? साथ ही, डेटा बहुत स्थिर है - यह लेनदेन के लिए लेनदेन नहीं है। धन्यवाद। –

+0

मैं लिंक का उपयोग नहीं करता लेकिन मेरी समझ यह है कि आप कुछ अलग-अलग उपयोग करके अलगाव स्तर को स्पष्ट रूप से सेट कर सकते हैं: अलगाव लेवेल = सिस्टम। ट्रांस्पेक्शन.इसेलेशन लेवेल। रीड अनन्य ... हालांकि जब आप कहते हैं कि डेटा अपेक्षाकृत स्थिर है, तो भी मैं अनुमान लगा रहा हूं कि या तो (ए) जिस क्वेरी की आप तुलना कर रहे हैं वह वास्तव में भेजा नहीं गया है, या (बी) आपका डेटाकॉन्टेक्स्ट पुराना है। –

1

आप सर्वर पर भेजे गए वास्तविक SQL को जांचने के लिए DebuggerWriter का उपयोग कर सकते हैं।

+0

धन्यवाद, मैंने पहले ही ऐसा ही किया है, उसी परिणाम के साथ। जब मैंने नोट किया कि मैंने फ़ाइल को लिखने के लिए "DataContext लॉग प्रॉपर्टी" का उपयोग किया है, तो मूल पोस्ट में मेरा यही मतलब था। जब तक आप कुछ और मतलब नहीं था। यदि हां, तो कृपया स्पष्ट करें। –

1
qry.ToList() 

यह कथन आपको इच्छित सूची बनाता है और देता है। यदि आप बाद में सूची का उपयोग करना चाहते हैं तो आपको परिणाम को कुछ (जैसे स्थानीय चर) को असाइन करना होगा।

संपादित करें: अद्यतन के लिए धन्यवाद।

मुझे लगता है कि वहाँ कुछ आप हमें बता नहीं कर रहे हैं कि यह भी एक समस्या हो सकती है होना चाहिए, और इसे यहाँ रहते हो सकता है:

Dim db as MyDataContext = MyGetDataContextHelper() 

इस विधि से एक आप जुड़े रूप में एक ही डेटाबेस से कनेक्ट करता है जब आपने एसक्यूएल स्टूडियो का इस्तेमाल किया था?

  • डेटाकॉन्टेक्स्ट की कनेक्शन प्रॉपर्टी की जांच करें।
  • सुनिश्चित करें कि एसक्यूएल प्रोफाइलर के साथ इसे देखकर डेटाबेस को क्वेरी जारी की गई है।
  • एक बहुत ही सरल प्रश्न जारी करें और पुष्टि करें कि यह सही परिणाम देता है।
+0

मेरा कोड पढ़ना चाहिए चाहिए qry.ToList(), क्योंकि कोड स्निपेट सूची लौटने वाले फ़ंक्शन का हिस्सा है। मैंने इसे प्रतिबिंबित करने के लिए कोड संपादित किया है। –

1

यह मूर्खतापूर्ण लग सकता है लेकिन हमेशा जांच करने के लिए एक अच्छा है, क्या आप एसएसएमएस में उसी डेटाबेस वातावरण से कनेक्ट हो रहे हैं जो आप अपने आवेदन से हैं? :)

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