2010-06-08 13 views
8

निम्नलिखित कोड:LINQ से SQL - आप ORDER BY के बाद WHERE का उपयोग क्यों नहीं कर सकते?

// select all orders 
var orders = from o in FoodOrders 
      where o.STATUS = 1 
      order by o.ORDER_DATE descending 
      select o; 

// if customer id is specified, only select orders from specific customer 
if (customerID!=null) 
{ 
    orders = orders.Where(o => customerID.Equals(o.CUSTOMER_ID)); 
} 

मुझे निम्न त्रुटि देता है:

Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Linq.IOrderedQueryable'. An explicit conversion exists (are you missing a cast?)

मैं अंत में छँटाई करके त्रुटि को ठीक:

// select all orders 
var orders = from o in FoodOrders 
      where o.STATUS = 1 
      select o; 

// if customer id is specified, only select orders from specific customer 
if (customerID!=null) 
{ 
    orders = orders.Where(o => customerID.Equals(o.CUSTOMER_ID)); 
} 

// I'm forced to do the ordering here 
orders = orders.OrderBy(o => o.ORDER_DATE).Reverse(); 

लेकिन मैं सोच रहा हूँ यह सीमा जगह क्यों है? एपीआई को इस तरह से डिज़ाइन किया गया था कि order by ऑपरेटर का उपयोग करने के बाद आप where बाधा नहीं जोड़ सकते हैं?

उत्तर

12

OrderBy की वापसी प्रकार IOrderedQueryable<T> है, ताकि orders चर (आंशिक रूप से क्योंकि तुम अंत में एक नहीं सेशन प्रक्षेपण है) के प्रकार है - लेकिन Where की वापसी प्रकार बस IQueryable<T> है। मूल रूप से आप एक नहीं सेशन प्रक्षेपण और एक परोक्ष टाइप स्थानीय चर और क्वेरी के अंतिम सक्रिय रूप से भाग एक आदेश, और आप तो चर पुन: असाइन करना चाहते हैं कर रहे हैं का एक मिश्रण मिल गया है। यह मूल रूप से एक दुखी संयोजन है।

आप इस तरह इसे ठीक कर सकता है:, वैकल्पिक रूप से

IQuerable<FoodOrders> orders = from o in FoodOrders 
           where o.STATUS == 1 
           order by o.ORDER_DATE descending 
           select o; 

// if customer id is specified, only select orders from specific customer 
if (customerID!=null) 
{ 
    orders = orders.Where(o => customerID.Equals(o.CUSTOMER_ID)); 
} 

यदि आप प्रदर्शन नहीं सेशन प्रक्षेपण स्पष्ट रूप से डॉट नोटेशन का उपयोग कर (मुझे लगता है एसक्यूएल अनुवादक सामना करने के लिए बहुत चालाक हो जाएगा!) प्रकार निष्कर्ष होगा ठीक हो जाएगा:

var orders = FoodOrders.Where(o => o.STATUS == 1) 
         .OrderByDescending(o => o.ORDER_DATE) 
         .Select(o => o); 

// if customer id is specified, only select orders from specific customer 
if (customerID!=null) 
{ 
    orders = orders.Where(o => customerID.Equals(o.CUSTOMER_ID)); 
} 

या एक अंतिम और थोड़ा अजीब सुझाव के रूप में, तो आप सिर्फ अपने प्रारंभिक where और orderby खंड का क्रम बदल सकता है। यह वस्तुओं के लिए LINQ में एक बुरा विचार होगा, लेकिन एक फर्क एसक्यूएल करने के लिए LINQ में नहीं करना चाहिए: OrderBy और OrderByDescending वापसी IOrderedQueryable तो: "क्यों" एपीआई के डिजाइन के मामले में

var orders = from o in FoodOrders 
      order by o.ORDER_DATE descending 
      where o.STATUS == 1 
      select o; 

// if customer id is specified, only select orders from specific customer 
if (customerID!=null) 
{ 
    orders = orders.Where(o => customerID.Equals(o.CUSTOMER_ID)); 
} 

अब, कि आप इसे ThenBy और ThenByDescending के साथ श्रृंखलाबद्ध कर सकते हैं जो कि मौजूदा शब्द होने पर निर्भर करता है कि यदि आप देखते हैं कि मेरा क्या मतलब है, तो वे माध्यमिक बन सकते हैं।

+0

नो-सेशन जिज्ञासा क्या है? – MCS

+0

यह वास्तव में एक संपूर्ण जवाब है और एक महान स्पष्टीकरण है। धन्यवाद। – MCS

+0

@ एमएमसीएस: मेरा मतलब है नो-ऑप प्रक्षेपण - एक चुनिंदा खंड जो कि पहले से मौजूद है का चयन करता है, अगर आप देखते हैं कि मेरा क्या मतलब है। –

4

यह ध्यान रखना महत्वपूर्ण है कि var दृढ़ता से टाइप किया गया है और संकलन समय पर व्याख्या किया जाता है। आपका पहला कोड यह अनिवार्य रूप से एक ही रूप में झलकी:

IOrderedQueryable<FoodOrders> orders = from o in FoodOrders 
     where o.STATUS = 1 
     order by o.ORDER_DATE descending 
     select o; 

जब आप कोड इस तरह से यह स्पष्ट हो जाता है कि क्यों आप एक चर IOrderedQueryable के रूप में घोषित करने के लिए एक IQueryable असाइन नहीं कर सकते लिखें।

आप उसी तरह से वर नहीं सोच सकते हैं आप आपत्ति होगा

object aString = "Testing..."; 
var bString = "Testing..."; 

aString = 1; // Works 
bString = 1; // Fails because 1 is not a string 

http://msdn.microsoft.com/en-us/library/bb384061.aspx

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