2011-11-08 77 views
2

我有一個簡單的foreach循環,通過產品ID的我已經存儲在用戶的上籃得手,並從數據庫中查找產品的詳細信息中附加的IQueryable。如何循環

正如你可以從我的代碼中看到的,我有什麼目前將返回屏幕上的最後一個項目 - 作爲變量在循環內覆蓋。我希望能夠對此進行連接,以便我只能在購物籃中顯示商品的產品詳細信息。

我知道我可以做我使用中繼器的東西很容易像商店只ProductIDs和onitemdatabound那裏調用數據庫中,但我想如果可能的話,使只有一個數據庫調用。

目前,我有以下的(除去複雜的示例連接,但如果這事讓我知道):

IQueryable productsInBasket = null; 
    foreach (var thisproduct in store.BasketItems) 
    { 
     productsInBasket = (from p in db.Products 
           where p.Active == true && p.ProductID == thisproduct.ProductID 
           select new 
           { 
            p.ProductID, 
            p.ProductName, 
            p.BriefDescription, 
            p.Details, 
            p.ProductCode, 
            p.Barcode, 
            p.Price 
           }); 
    } 

    BasketItems.DataSource = productsInBasket; 
    BasketItems.DataBind(); 

感謝您的幫助!

回答

7

這聽起來像你真的想是這樣的:

var productIds = store.BasketItems.Select(x => x.ProductID).ToList(); 
var query = from p in db.Products 
      where p.Active && productIds.Contains(p.ProductID) 
      select new 
      { 
       p.ProductID, 
       p.ProductName, 
       p.BriefDescription, 
       p.Details, 
       p.ProductCode, 
       p.Barcode, 
       p.Price 
      }; 
+0

嗨,喬恩,謝謝你。它工作得很好!我永遠不會想到過像這樣做過濾器。方便知道:) –

0

在Jon的回答,這只是正常的的IQueryable然而,將轉化爲一個IEnumerable,因爲你就可以調用ToList()。這將導致查詢被執行並且檢索到答案。對於你的情況,這可能是可以的,因爲你想檢索一籃子產品,並且產品數量可能會相當小。

我,然而,面對類似的情況,在這裏我想找回朋友的成員。友誼取決於兩個成員屬於哪個組 - 如果他們至少分享一個組,那麼他們就是朋友。因此,我必須爲某個成員檢索所有組的所有成員,然後從這些組中檢索所有成員。

的ToList的方法並不適用於我的情況,因爲這會我要處理我的朋友以各種方式,例如每次執行查詢找到我們可以分享的東西。從數據庫中檢索所有成員,而不是僅僅處理查詢並在最後時刻執行它,將會導致性能下降。

不過,我在這種情況下的第一次嘗試就是這樣做 - 檢索屬於我的所有組(IQueryable),初始化List結果(IEnumerable),然後遍歷所有組並將所有成員追加到結果中不在列表中。最後,由於我的界面強制要返回IQueryable,所以我使用AsIQueryable返回了列表。

這是一個討厭的代碼,但至少它工作。它看起來是這樣的:

var result = new List<Member>(); 
foreach (var group in GetGroupsForMember(member)) 
    result.AddRange(group.GroupMembers.Where(x => x.MemberId != member.Id && !result.Contains(x.Member)).Select(groupMember => groupMember.Member)); 
return result.AsQueryable(); 

然而,這是不好的,因爲我所有的共享成員添加到列表,然後將列表轉換爲IQueryable只是爲了滿足我的後置條件。我會從數據庫中檢索所有受影響的成員,每次我都想用它們做東西。

想象一個分頁列表 - 那我就只是想從該列表中挑選出一定的範圍內。如果這是通過IQueryable完成的,則查詢只是使用分頁語句完成的。如果這是通過IEnumerable完成的,則查詢已經被執行並且所有操作都被應用於內存中的結果。 (你也許還會注意到,我也向下瀏覽實體的關係(GroupMember => Member),這會增加耦合性,從而可能導致各種惡劣的情況。我也想刪除這種行爲)。

所以,今晚,我又圓,結束了一個更簡單的方法,在這裏我選擇這樣的數據:

var groups = GetGroupsForMember(member); 
var groupMembers = GetGroupMembersForGroups(groups); 
var memberIds = groupMembers.Select(x => x.MemberId); 
var members = memberService.GetMembers(memberIds); 

兩種獲取方式兌現了IQueryable的和從未將其轉換爲一個列表或者任何其他IEnumerable。第三行只是在IEnumerable的頂部執行一個LINQ查詢。最後一行只取得成員ID並從另一個服務中檢索所有成員,這些成員也僅與IQueryables一起工作。

這在性能方面可能仍然很糟糕,但如果需要,我可以稍後對其進行優化。至少,我避免加載不必要的數據。

讓我知道,如果我在這裏是非常錯誤的。