2011-05-14 41 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