我有这个Sql语句
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 ...
答案 0 :(得分: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();
答案 1 :(得分: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();
如果有人有更好的解决方案,那么我全都是耳朵......