2016-05-25 54 views
5

鑑於返回數據:使用名單<元組<int, int>>中的LINQ

List<int> myList; 

如果我想返回數據,其中記錄ID被包含在這個名單,我只想做:

var q = db.Table.Where(c=> myList.Contains(c.ID)); 

但是,給出:

List<Tuple<int, int>> myList; 

我該如何編寫一個Linq查詢來返回滿足這兩個條件的記錄?隨着一個數據點我會寫:

var q = db.Table.Where(c=> 
      c.ID == myList.Item1 
      && c.AnotherValue == myList.Item2); 

我將如何轉換上述聲明上List<Tuple<int, int>>工作?

回答

6

A Tuple是一個不能被您的Linq Provider轉換爲sql的結構。溶液可進行切換到LINQ到對象

var q = db.Table.AsEnumerable() 
       .Where(c=> myList.Any(tuple => c.ID == tuple.Item1 && 
              c.AnotherValue == tuple.Item2)); 

但是這個解決方案的惡劣的是,你會從該表中加載的所有行內存篩選。

另一種解決方案可以使用Linqkit

var predicate = PredicateBuilder.False<Table>(); 

foreach (string t in myList) 
{ 
    predicate = predicate.Or(c =>c.ID == t.Item1 && c.AnotherValue == t.Item2)); 
} 

db.Table.AsExpandable().Where(predicate); 

你會發現關於這個link

+0

是的,但對於多個值嗎?如果我有100對的列表,我不想在每個列表上運行查詢。 –

+0

謝謝,PredicateBuilder在這裏看起來不錯! –

+0

不客氣;) – octavioccl

1
var q = db.Table.AsEnumerable().Where(c => myList.Any(tuple => c.ID == tuple.Item1 && 
               c.AnotherValue == tuple.Item2)); 

隨着Any您可以檢查是否有在myList比賽你的病情至少一個元素。

但是正如@octaviocci指出的那樣,這不能轉換爲SQL,因此您需要先調用AsEnumerable()並在本地執行過濾,如果存在大量不相關的記錄,則這可能不是您想要的。

0

下面這最後的解決方案的更多信息是說明一種方法的一些示例代碼:

DataTable dt = new DataTable("demo"); 
// hydrate your table here... 

List<Tuple<int, int>> matches = new List<Tuple<int, int>>(); 

Func<List<Tuple<int,int>>, DataRow, bool> RowMatches = (items, row) => { 

     var rowValue1 = (int)row["Id"]; 
     var rowValue2 = (int)row["SomeOtherValue"]; 

     return items.Any(item => item.Item1 == rowValue1 && item.Item2 == rowValue2); 
    }; 

var results = dt.Rows.Cast<DataRow>().Where(r => RowMatches(matches, r)); 
Console.WriteLine(results.Any()); 
0

請參閱下面的代碼:

List<Tuple<int, int>> myList; 

var set = new HashSet(myList); 

var q = db.Table.AsEnumerable().Where(c=> set.Contains(new Tuple(c.ID, c.AnotherValue))); 

請注意,散列集用於性能優化大myListWhere子句的執行。

+0

這難道不是簡單地將set1的ANY項與任何set2項相匹配嗎? –

0

由於Tuple不能Linq to Entities使用,你可以嘗試這樣的事:

List<int> items1 = myList.Select(t => t.Item1).ToList(); 
List<int> items2 = myList.Select(t => t.Item2).ToList(); 

var q = db.Table.GroupBy(m => { m.ID, m.AnotherValue }) 
       .Where(g => items1.Contains(g.Key.ID) && 
          items2.Contains(g.Key.AnotherValue)) 
       .SelectMany(g => g); 
相關問題