2011-10-12 15 views
37

मेरे पास ओडीटा सेवा है जहां मैं आईडी की सूची द्वारा फ़िल्टर करने की कोशिश कर रहा हूं; एसक्यूएल बराबर होगा कुछ की तरह:ओडाटा "जहां सूची में आईडी" क्वेरी

SELECT * FROM MyTable WHERE TableId IN (100, 200, 300, 400) 

संपत्ति मैं पर फिल्टर करने के लिए कोशिश कर रहा हूँ कोई Int32 के रूप में लिखा गया हो। मैं निम्नलिखित है, जो मुझे एक त्रुटि देता है की कोशिश की है "ऑपरेटर संकार्य प्रकार 'Edm.String' और 'Edm.Int32' के साथ असंगत 'जोड़ें'":

string ids = ",100,200,300,400,"; 
from m in provider.Media where ids.Contains("," + t.media_id.ToString() + ",") 
रूप

string ids = ",100,200,300,400,"; 
from m in provider.Media where ids.Contains("," + t.media_id + ",") 

रूप में अच्छी तरह

और

string ids = ",100,200,300,400,"; 
from m in provider.Media where ids.Contains("," + Convert.ToString(t.media_id) + ",") 

और

string ids = ",100,200,300,400,"; 
from m in provider.Media where ids.Contains(string.Concat(",", t.media_id, ",")) 

जैसा कि आप देख सकते हैं, वर्तमान में मैं सेवा पूछने के लिए LINQ का उपयोग कर रहा हूं।

क्या कोई तरीका है जो मैं कर रहा हूं, या क्या मैं एक टेक्स्ट फ़िल्टर बनाने और AddQueryOption का उपयोग करके अटक गया हूं, और सूची के माध्यम से पुनरावृत्त कर रहा हूं और मैन्युअल रूप से "या media_id eq 100" खंड जोड़ रहा हूं?

+1

https://gist.github.com/mausch/6893533 –

उत्तर

31

यह एक

var ids = new [] { 100, 200, 300 } ; 
var res = from m in provider.Media 
      from id in ids 
      where m.media_id == id 
      select m; 

कोशिश DataServices क्वेरी करने पर msdn पर एक व्यापक वर्णन है।

एक और दृष्टिकोण

var results = provider.Media 
    .AddQueryOption("$filter", "media_id eq 100"); 

हो सकता है और के बाद से OData IN बयान का समर्थन नहीं करता तो आप इस

.AddQueryOption("$filter", "(media_id eq 100) or (media_id eq 200) or ..."); 

तरह फिल्टर शर्त के साथ ऊपर आ जाएगा जो आप पाश या LINQ Select का उपयोग कर निर्माण कर सकते हैं और string.Join:

var ids = new [] { 100, 200, 300 }; 
var filter = string.Join(" or ", ids.Select(i=> $"(media_id eq {i})")); 
var results = provider.Media.AddQueryOption("$filter", filter); 

अद्यतन: फ़िल्टर ऑपरेशन field=["a","b"] है हालांकि इसका मतलब कुछ अलग है।

UPDATE2: OData V4 में लैम्ब्डा भाव any और all, शाब्दिक शृंखला ["a", "b"] के साथ रखा वे in के रूप में काम कर सकते हैं, लेकिन मैं OData.org

पर v4 एंडपॉइंट का उपयोग करके उदाहरण काम कर
+0

यह एक त्रुटि फेंकता है: "लिंक अभिव्यक्ति को यूआरआई में अनुवाद करने में त्रुटि: विधि 'चयन' समर्थित नहीं है।" अच्छा विचार, यद्यपि। – technophile

+0

यही वह है जो मैंने अपेक्षित था। इसलिए दूसरा दृष्टिकोण का उपयोग करने का आपका एकमात्र विकल्प, जो आपके मामले में आसान होगा जब आप नहीं जानते कि आपके पास पहले से मौजूद सूची में कितने तत्व हैं – vittore

+0

हाँ, $ फ़िल्टर के साथ लूप वह है जो मैं कर रहा हूं। यहां उम्मीद है कि मैं यूआरएल लंबाई सीमा से अधिक कभी प्रबंधित नहीं करता! :- डी – technophile

12

विस्तार साथ आने के लिए सक्षम नहीं था वहाँ है vittore के जवाब (जो के दूसरे भाग सही जवाब है) पर, मैं एक डेमो परियोजना के लिए निम्न जैसा कुछ लिखा है:

var filterParams = ids.Select(id => string.Format("(media_id eq {0})", id)); 
var filter = string.Join(" or ", filterParams); 
var results = provider.Media.AddQueryOption("$filter", filter).Execute().ToList(); 

यह सुंदर नहीं है, और आप का उपयोग नहीं करना चाहते यह आईडी की एक बड़ी सूची के लिए (> ~ 60), लेकिन यह चाल करेगा।

0

अगर हमें 50 या 60 आईडी की आवश्यकता है तो हमें 2 या उससे अधिक समांतर कॉल करने की सलाह दी जाती है और उन्हें समवर्ती शब्दकोश या कुछ ऐसा ही मिलता है जैसे हमें सर्वर से परिणाम मिलते हैं।हालांकि इससे सर्वर पर कॉल की संख्या बढ़ जाती है, लेकिन क्योंकि हम धीरे-धीरे क्लाउड पर्यावरण पर जा रहे हैं, यह मेरी राय में एक बड़ी समस्या नहीं होनी चाहिए।

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