2010-03-18 17 views
7

मैं LINQ-SQL का उपयोग अपने डीएएल के रूप में करता हूं, फिर मेरे पास डीबी नामक एक प्रोजेक्ट है जो मेरे बीएलएल के रूप में कार्य करता है। एसक्यूएल डाटाबेस से डेटा पढ़ने/लिखने के लिए विभिन्न अनुप्रयोगों के बाद बीएलएल तक पहुंचें।इन LINQ प्रश्नों के बीच क्या अंतर है?

public IEnumerable<SystemSalesTaxList> Get_SystemSalesTaxList() 
{ 
     return from s in db.SystemSalesTaxLists 
       select s; 
} 

public SystemSalesTaxList Get_SystemSalesTaxList(string strSalesTaxID) 
{ 
    return Get_SystemSalesTaxList().Where(s => s.SalesTaxID == strSalesTaxID).FirstOrDefault(); 
} 

public SystemSalesTaxList Get_SystemSalesTaxListByZipCode(string strZipCode) 
{ 
    return Get_SystemSalesTaxList().Where(s => s.ZipCode == strZipCode).FirstOrDefault(); 
} 

सभी सुंदर सीधे आगे मैंने सोचा:

मैं एक विशेष तालिका के लिए मेरे BLL में इन विधियों की है।

Get_SystemSalesTaxListByZipCode हमेशा एक शून्य मूल्य लौटा रहा है, भले ही उस तालिका में मौजूद ज़िप कोड हो।

public SystemSalesTaxList Get_SystemSalesTaxListByZipCode(string strZipCode) 
{ 
    var salesTax = from s in db.SystemSalesTaxLists 
        where s.ZipCode == strZipCode 
        select s; 

    return salesTax.FirstOrDefault(); 
} 

क्यों अन्य विधि एक ही वापस नहीं करता है, क्वेरी के रूप में समान होना चाहिए:

अगर मैं इस तरह विधि लिखते हैं, यह पंक्ति मैं चाहता हूँ रिटर्न?

ध्यान दें कि, ओवरलोडेड Get_SystemSalesTaxList(string strSalesTaxID) रिकॉर्ड रिकॉर्ड करता है जब मैं इसे वैध SalesTaxID देता हूं।

क्या इन "सहायक" प्रकार के वर्गों को लिखने का एक और अधिक प्रभावी तरीका है?

धन्यवाद!

+0

बेवकूफ प्रश्न - क्या आप वाकई ज़िपकोड में 'Get_SystemSalesTaxListByZipCode' में गुजर रहे हैं? – Oded

+1

समस्या, पहचान के रूप में, 'IEnumerable ' - लेकिन मैं सिर्फ यह कहने के लिए रो रहा हूं कि "शायद यह हंगेरी नोटेशन के बारे में शिकायत करने का तरीका है"; -पी –

उत्तर

7

यह संभवत: LINQ हैंडल IEnumerable<T> और IQueryable<T> हैंडल के विभिन्न तरीकों से नीचे है।

आपने Get_SystemSalesTaxList को IEnumerable<SystemSalesTaxList> पर लौटने के रूप में घोषित किया है। इसका मतलब है कि, जब आपके पहले कोड नमूने में, आप Get_SystemSalesTaxList के परिणामों पर कहां ऑपरेटर लागू करते हैं, तो यह Enumerable.Where एक्सटेंशन विधि के लिए हल हो जाता है। (ध्यान दें कि क्या मायने रखती है घोषित प्रकार है हाँ, क्रम Get_SystemSalesTaxList एक IQueryable<SystemSalesTaxList> लौटने पर है, लेकिन इसकी घोषित प्रकार -। क्या संकलक देखता है - IEnumerable<SystemSalesTaxList> है।) Enumerable.Where लक्ष्य से अधिक निर्दिष्ट नेट विधेय चलाता है अनुक्रम। इस मामले में, यह GetSystemSalesTaxList द्वारा लौटाए गए सभी SystemSalesTaxList ऑब्जेक्ट्स पर पुनरावृत्त होता है, जहां ज़िपकोड संपत्ति निर्दिष्ट ज़िप कोड स्ट्रिंग के बराबर होती है (.NET स्ट्रिंग == ऑपरेटर का उपयोग करके)।

लेकिन आपके अंतिम कोड नमूने में, आप कहां ऑपरेटर को db.SystemSalesTaxList पर लागू करते हैं, जिसे IQueryable<SystemSalesTaxList> प्रकार के रूप में घोषित किया जाता है। तो उस नमूने में जहां ऑपरेटर Queryable.Where पर हल हो जाता है, जो निर्दिष्ट predicate अभिव्यक्ति का अनुवाद SQL में करता है और इसे डेटाबेस पर चलाता है।

तो ज़िप कोड विधियों में क्या भिन्न है यह पहला है कि .NET में C# s.ZipCode == strZipCode परीक्षण चलाता है, और दूसरा SQL क्वेरी WHERE ZipCode = 'CA 12345' (पैरामीटर एसक्यूएल वास्तव में लेकिन आपको विचार मिलता है) में अनुवाद करता है। ये अलग-अलग परिणाम क्यों देते हैं? सुनिश्चित करना मुश्किल है, लेकिन सी # == भविष्यवाणी केस-संवेदी है, और आपकी collation सेटिंग्स के आधार पर SQL एसक्यूएल केस-संवेदी हो सकता है या नहीं। तो मेरा संदेह यह है कि strZipCode मामले में डेटाबेस ज़िप कोड से मेल नहीं खाता है, लेकिन दूसरे संस्करण में SQL सर्वर संयोजन इस पर चिकनाई कर रहा है।

सबसे अच्छा समाधान शायद IQueryable<SystemSalesTaxList> लौटने के लिए Get_SystemSalesTaxList की घोषणा को बदलने के लिए है। इसका मुख्य लाभ यह है कि इसका मतलब है कि Get_SystemSalesTaxList पर बनाए गए प्रश्न डेटाबेस पक्ष को निष्पादित किए जाएंगे।फिलहाल, आपकी विधियां डेटाबेस तालिका में को वापस खींच रही हैं और इसे क्लाइंट साइड फ़िल्टर कर रही हैं। घोषणा बदलना आपके प्रश्नों को एसक्यूएल में अनुवादित करेगा और वे अधिक कुशलता से चलेंगे, और उम्मीद है कि सौदेबाजी में आपके ज़िप कोड मुद्दे को हल करेंगे।

+0

मुझे समझ में आता है, और बिल्कुल ठीक था जवाब मैं सवाल पोस्ट करते समय पाने के लिए देख रहा था! धन्यवाद। – SnAzBaZ

1

वास्तविक समस्या यहां IEnumerable<T> का उपयोग है, जो प्रश्नों की "संरचना" को तोड़ती है; इस दो प्रभाव होते हैं:

  • आप सभी (या कम से कम, अधिक से अधिक आप की जरूरत) हर बार अपनी तालिका के पढ़ रहे हैं, भले ही आप एक ही पंक्ति
  • आप चल रहे हैं के लिए पूछना LINQ करने वाली वस्तुओं नियम है, इसलिए मामले संवेदनशीलता

इसके बजाय लागू होता है, आप आवश्यकतानुसार आप के साथ अतिरिक्त Where, OrderBy, Skip, Take, आदि कई प्रश्न गठबंधन करने के लिए अनुमति देता है आपका डेटा स्तर के अंदर IQueryable<T> का उपयोग किया जा करना चाहते हैं, और इसे बनाने के लिए है मिलान करने के लिए टीएसक्यूएल (और अपने डीबी के केस-सेंसिटीविटी नियमों का उपयोग करें)।

क्या इन "सहायक" प्रकार कक्षाओं को लिखने का एक और अधिक प्रभावी तरीका है?

अधिक कुशल के लिए (डिबग करने के लिए कम कोड, पूरे मेज, पहचान-नक्शा शॉर्ट सर्किट अतिरिक्त खोज के लिए (के बेहतर इस्तेमाल धारा नहीं है FirstOrDefault आदि) के माध्यम से):

public IEnumerable<SystemSalesTaxList> Get_SystemSalesTaxList() 
{ 
    return db.SystemSalesTaxLists; 
} 

public SystemSalesTaxList Get_SystemSalesTaxList(string salesTaxID) 
{ 
    return db.SystemSalesTaxLists.FirstOrDefault(s => s.SalesTaxID==salesTaxID); 
} 

public SystemSalesTaxList Get_SystemSalesTaxListByZipCode(string zipCode) 
{ 
    return db.SystemSalesTaxLists.FirstOrDefault(s => s.ZipCode == zipCode); 
} 
+0

हालांकि यहां मेरा नोट भी देखें (http://stackoverflow.com/questions/2469816/what-is-the-best-way-to-determine-if-table-already-has-record-with-specific-id/ 2469836 # 2469836) 'कहां (predicate) के बीच के अंतर के लिए .इसऑरडिडॉल्ट() 'और' FirstOrDefault (predicate)' .NET 3.5/3.5SP1/4.0 –

+0

के बीच अंतर के लिए धन्यवाद, मेरे प्रश्न के दो महान जवाब नहीं! – SnAzBaZ

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