2011-04-14 70 views
0

所以我在一個asp.net mvc項目的Linq-To-Entities。稍微複雜多對多linq查詢讓我卡住

我總是會對這種查詢感到困惑。

我的模式是:

ProductTag 
+TagName 
+<<ProductNames>>//Many-to-many relationship 

ProductName 
+FullName 
+<<Tag>>//Many-to-many relationship 

PurchaseRecord 
+Amount 
+<<ProductName>>//one productname can be linked to Many purchase records. 

我需要得到和所有購買的一個給定的標籤。

這是我試過的。

ProductTag thetag//could be some tag 

decimal total = myentities.PurchaseRecords 
        .Where(x => thetag.ProductNames.Any 
         (a => a.FullName == x.ProductName.FullName)) 
         .Sum(s => s.Amount); 

我試着改變一些事情,用Contains試過,但我知道我根本錯誤的地方。

我不斷收到:

無法創建類型的恆定值「產品名稱」。在此上下文中僅支持基本類型(如Int32,String和Guid)。

更新 所以與它下面@Alexandre Brisebois的幫助工作只是這樣的:

var total= item.ProductNames.SelectMany(x => x.PurchaseRecords) 
              .Sum(s => s.Amount); 

回答

1

當你得到這種錯誤,你需要做的LINQ查詢以外的所有的評價以變​​量形式傳遞值。

您的查詢的問題是thetag.ProductNames.Any()不在上下文中。

此評估不會轉換爲SQL,因爲它不是字符串/ guid或int。

您將需要在查詢中查詢此對象並從此對象進行評估。

我不確定這是否清楚。

你需要做的像

var query1 = (from x in tags where x.tagID = id select x.ProductNames) 
                  .SelectMany(...) 

的東西選擇多是因爲你選擇的集合ProductNames,需要將其帶回作爲平面組/集合FO,你可以在上面做一個.Any()在下一個查詢中。

然後用這個,做一個query1.Any(logic)

decimal total = myentities.PurchaseRecords. 
          Where(x => query1.Any 
           (a => a.FullName == x.ProductName.FullName)) 
           .Sum(s => s.Amount); 

通過這樣做,你會留在LINQ到實體,而不是轉換爲LINQ的對象。

ForEach不是一個選項,因爲這將迭代集合。

+0

對不起,如果我的代碼是不明確的。 'GetAll()'就是我調用'entitiescontext'的庫。更新的問題。你能舉一個例子來說明你的第一句話嗎?我會通過什麼? – gideon 2011-04-14 17:59:39

+0

好吧我想我明白了,但這意味着我將不得不像'foreach(item in tag.ProductName)=>找到具有該項目的PurchaseRecords'right? – gideon 2011-04-14 18:06:33

+0

非常好!謝謝非常多的Alenxandre這工作:'var total = item.ProductNames.SelectMany(x => x.PurchaseRecords).Sum(s => s.Amount);'我還沒有掌握在我的腦海中,我會寫這個作爲一個linq查詢(查詢符號),但我很高興它的工作原理。 – gideon 2011-04-14 18:28:56

0

您可以使用AsEnumerable方法在C#而不是SQL Server上執行某些查詢部分。當你在內存中有部分數據(對象集合)時,通常需要這樣做,因此在查詢中使用它們並不容易。您必須在.net端執行部分查詢執行。您的問題PLZ嘗試

decimal total = myentities.PurchaseRecords.AsEnumerable() 
        .Where(x => thetag.ProductNames.Any 
         (a => a.FullName == x.ProductName.FullName)) 
         .Sum(s => s.Amount); 

PLZ訪問這個link找到更多關於AsEnumerable

+1

這可能會導致他的性能問題,如果有很多PurchaseRecords,因爲它將查詢表中的所有PurchaseRecords。 – 2011-04-14 18:16:45

+0

是的,這會。除非你真的需要它們,否則很好的解決方案並不是把內存中的對象放在第一位。但如果你想這樣,這是解決方案 – 2011-04-14 18:18:09