2010-07-22 46 views
4

我有一個多對多的關係如下:LINQ多對多地獄 - 查詢,其中包含了所有

產品 的ProductID 說明

產品屬性 ProductFeatureID 的ProductID FEATUREID

功能 特徵ID 描述

任何產品可以有許多功能。

然後,我會發現一個叫做「SearchFeatures」的iQueryable,它包含兩個我想要搜索的特定對象。

我想找到具有所有這些功能的產品!

E.g.這樣的事情將是很好:

return db.Products.Where(x => x.Features.ContainsAll(SearchFeatures)); 

什麼是實現這一目標使用LINQ最徹底的方法?

非常感謝。

回答

5
IQueryable<Products> products = db.Products; 
foreach (var feature in SearchFeatures) 
{ 
    Feature tmpFeature = feature; 
    products = products 
     .Where(x=>x.ProductFeatures.Any(y=>y.FeatureID == tmpFeature.FeatureID)); 
} 
+0

如果SearchFeatures是一個本地集合,這是一個很好的解決方案。 – 2010-07-22 15:48:53

+0

弗朗西斯科你絕對的傳奇。 大衛B非常好點,因爲這正是我的情況。 SearchFeatures是一個本地集合,因此我得到了其他方法的LINQ錯誤。不能交叉查詢本地和數據庫/已提交集合的組合。 弗朗西斯科的解決方案完全處理這個問題,我的代碼像夢一樣運行。非常感謝你們兩位。 – Aaron 2010-07-23 04:02:51

+1

是的!這正是我所期待的!這是構建一個真正的ContainsAll(不受linq-to-sql支持)的另一種方法,非常感謝! – 2014-04-18 17:42:40

1

像這樣的東西應該工作

public partial class Product 
{ 
    public IEnumerable<Feature> Features 
    { 
     get 
     { 
      return ProductFeatures.SelectMany(pf => pf.Feature); 
     } 
    } 
} 

Products.Where(p => SearchFeatures.All(sf => p.Features.Count(f => f.ID == sf.ID) > 0)); 
+0

這是爲我工作很好,除了我沒有提到我的SearchFeatures是一個本地收藏,所以我當時就犯了錯誤。但整潔的解決方案,仍值得一點 - 謝謝。 – Aaron 2010-07-23 04:09:46

+0

@Aaron:是的,就像你在最後一行代碼中看到的那樣,它根本不在任何上下文中。也許這種格式是誤導性的,但無論如何,這個調用只是在你正在進行調用的地方,而'SearchFeatures'可能是該範圍內的任何局部變量。 – 2010-07-23 07:15:17

+0

謝謝大衛。你的代碼看起來很乾淨,但我仍然得到這個錯誤「除了Contains()運算符外,本地序列不能用於查詢運算符的LINQ to SQL實現。」我只是第二次插上它再次嘗試,因爲我喜歡這個解決方案的簡單性,但它並不開心,並且給我帶來了錯誤。我的代碼是: SearchResults = SearchResults.Where )); – Aaron 2010-07-23 07:46:51

1
IQueryable<Product> query = db.Products 
    .Where(p => SearchFeatures 
    .All(sf => 
     p.ProductFeatures.Select(pf => pf.Feature).Contains(sf) 
    ) 
); 
+0

這個解決方案非常優雅,我會在SearchFeatures不是本地的情況下繼續使用它。非常感謝。 – Aaron 2010-07-23 04:03:20

2
from item in db.Products 
where item.ProductFeatures.Where(x=>featIdList.Contains(x.FeatureId)).Count() == featIdList.Count 
select item 

這應該這樣做。 featIdList就是你要找的

+0

感謝Mike,他人的另一個解決方案,我認爲如果我的收藏不是本地的,它會工作得很好。 – Aaron 2010-07-23 04:11:15

+0

@Aaron這應該與本地收藏。我已經成功地使用過它。只要確保featIdList是一個ID列表,而不是功能列表 – Mike 2010-07-23 13:22:27

0

不知道,如果它沒有在2010年存在的功能ID的列表,但現在你可以這樣做:

var myArray = new[] { 2, 3 }; 
q = myArray.Aggregate(q, (current, myArrayItem) => current.Where(x => x.Producs.Any(y => y.Id == myArrayItem)));