2011-05-14 45 views
7

我有這條SQL語句轉換這個SQL以拉姆達爲EF 4代碼第一

SELECT * FROM Game 
     INNER JOIN Series ON Series.Id = Game.SeriesId 
     INNER JOIN SeriesTeams ON SeriesTeams.SeriesId = Series.Id 
     INNER JOIN Team ON Team.Id = SeriesTeams.TeamId 
     INNER JOIN TeamPlayers ON TeamPlayers.TeamId = Team.Id 
     INNER JOIN Player ON Player.Id = TeamPlayers.PlayerId 
    WHERE AND Game.StartTime >= GETDATE() 
     AND Player.Id = 1 

,我想轉換成一個lambda表達式。

這是如何工作的。

一個遊戲只能加入1個系列,但一個系列當然可以有很多遊戲。一個系列可以有很多團隊,一個團隊可以加入許多系列。 一名球員可以參加很多球隊,而球隊中有很多球員。

SeriesTeams和TeamPlayers僅僅是多到許多由EF創建舉行系列/團隊和團隊之間的引用表/玩家

在此先感謝...

編輯:我用的是EF 4 CTP5,並希望將答案作爲lambda函數,或者在linq中,如果更容易...

回答

3

好吧,首先,如果你想確保一切都渴望加載當你運行你的查詢,你應該增加一個顯Include

context. 
Games. 
Include(g => g.Series.Teams.Select(t => t.Players)). 
Where(g => 
     g.StartTime >= DateTime.Now && 
     g.Series.Teams.Any(t => t.Players.Any(p => p.Id == 1))). 
ToList(); 

然而,正如我在我的評論中提到,這不會產生相同的結果作爲您的SQL查詢,因爲你沒有過濾掉從孩子收集的球員。

EF 4.1有一些漂亮的Applying filters when explicitly loading related entities功能,但我無法讓它適用於子子集合,所以我認爲最接近原始查詢的方法是將結果投影到匿名對象上(或者你可以爲創建一個類,如果你以後需要圍繞通過這個對象):

var query = context. 
      Games. 
      Where(g => 
        g.StartTime >= DateTime.Now && 
        g.Series.Teams.Any(t => t.Players.Any(p => p.Id == 1))). 
      Select(g => new 
         { 
          Game = g, 
          Players = g. 
             Series. 
             Teams. 
             SelectMany(t => t. 
                 Players. 
                 Where(p => p.Id == user.Id)) 
         }); 

然後,你可以列舉,檢查結果:

var gamesAndPlayersList = query.ToList(); 
+0

嗨。我會試試看。我猜EF生成的SQL語句不像我的原始sql語句那麼「好」。一種方法是創建一個視圖,該視圖可以從不同的表中獲得我想要的信息,然後執行該視圖,然後創建此特殊實體以匹配該結果。不會像以上那樣好,但可以給我更好的數據庫性能。我必須做一些性能測試來決定是否值得做額外的工作。 – 2011-05-27 05:16:59

1

我確實找到了解決方案。

IList<Domain.Model.Games> commingGames = this.Games 
.Where(a => a.StartTime >= DateTime.Now && a.Series.Teams.Any(t => t.Players.Any(p => p.Id == user.Id))).ToList(); 

如果有人有更好的解決方案,然後我所有的耳朵..

+0

這會不會給予同樣的結果作爲你的SQL查詢,但。不同之處在於,SQL查詢僅返回具有'Id == 1'的玩家,而您的LINQ查詢將返回玩家1的遊戲列表,但與玩家1同組的所有玩家(子集合是未過濾)。這是你實際尋找的輸出嗎?此外,如果不進行延遲加載,您甚至無法訪問任何導航屬性(只有「遊戲」會從數據庫中加載)。你使用什麼版本的EF? – Yakimych 2011-05-22 11:46:17

+0

是的,我看到它是EF4 CTP5 - 抱歉,我沒有重新閱讀您的問題,並在發佈我的評論前查看編輯。任何不切換到EF4.1的原因,順便說一句? – Yakimych 2011-05-22 16:44:06

+0

對不起!我實際上使用EF4.1 EF4 CTP5必須是舊哈比特:)。關於我將球隊中的所有球員都當作球員1.我應該如何更改lambda表達式以僅顯示球員1的比賽? – 2011-05-26 10:42:57