2011-10-12 62 views
37

我在那裏,我想通過ID列表過濾OData服務;在SQL相當於將是這樣的:的OData「其中列表ID」查詢

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 + ",") 

以及

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("," + 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,並遍歷列表並手動添加「or 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; 

有上 msdn的全面描述上詢問DataService的。

另一種辦法是

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 Selectstring.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有Lambda表達式anyall,與數組文本["a", "b"]配對,他們可能工作爲in,但我沒能拿出工作示例使用V4端點在OData.org

+0

引發錯誤:「將Linq表達式轉換爲URI時出錯:不支持」Select「方法。」不過好的想法。 – technophile

+0

這是我的預期。所以你唯一的選擇就是使用第二種方法,當你不知道列表中有多少個元素時,使用第二種方法很容易 – vittore

+0

是的,帶有$ filter的循環是我最終做的。希望我永遠不會超過URL長度限制! :-D – 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(); 

這不是優雅,而且你不希望使用這是一個很大的ID列表(>〜 60),但它會做到這一點。

0

擴展在MCattle建議,如果我們需要更多的50個或60 IDS那麼它最好在2次或多個並行調用做,並將其添加到字典中併發或類似的東西,因爲我們從服務器獲取結果。雖然這增加了對服務器的呼叫數量,但由於我們正在慢慢轉向雲環境,所以在我看來這不應該是一個大問題。