使用IQueryable和Linq.Expressions速记加入吗?

时间:2019-11-26 06:29:19

标签: c# linq

我刚刚使该查询正常运行

int playerId = 1;
var x = from ghp in _context.GameHasPlayers
        from g in _context.Games
        where ghp.PlayerId == playerId && g.Id == ghp.GameId
        select new Game { };

它给了我一个IQueryable<Game>,我将其转换为列表return x.ToList();

但是我已经看到很多这样写的查询:

var a = _context.GameHasPlayers.Where(ghp => ghp.PlayerId == playerId);

其中var a变成IQueryable<GameHasPlayers>

我只想知道两件事

  1. 这是否在幕后使用相同的Linq.Expressions技术,只是语法(速记?)不同-该语法是否有特定名称? (用于谷歌搜索目的)
  2. 如何使用此语法编写第一个成功的查询?我被卡住了:

var a = _context.GameHasPlayers.Where(ghp => ghp.PlayerId == playerId); var b = _context.Games.Where(g => g.Id == a.GameId);

第二行无法识别a.GameId,这是一个有效字段,但是我想我无法像这样传递这组IQueryable标头。

在SQL中,我会写类似 IN _context.Games.Where(g => g.Id in a.GameId);

3 个答案:

答案 0 :(得分:4)

此技术称为Method chain Syntax。 方法链和查询语法都是Linq的一部分,并且是等效的。

您可以使用create以方法链语法编写查询:

Join

我首先重写了原始查询以对其进行过滤,然后将过滤后的结果与var res = _context.GameHasPlayers .Where(x => x.PlayerId == playerId) .Join(_context.Games, ghp => ghp.GameId, g => g.Id, (gameHasPlayer, game) => new Game { } ); 表联接起来,您可以从中获取更多数据。

答案 1 :(得分:1)

对于第2点:

var a = _context.GameHasPlayers.Where (ghp => ghp.PlayerId == playerId); 
var b = _context.Games.Where (g => a.Contains(x=> g.Id == x.GameId));

答案 2 :(得分:1)

您的查询等同于此类查询(并且此语法更好):

 var x = from ghp in _context.GameHasPlayers
         join g in _context.Games
         on new
         {
             playerId = ghp.PlayerId,
             gameId = ghp.GameId
         } equals new
         {
             playerId,
             gameId = g.Id
         }
         select new Game{ };

因此您可以将该查询重写为:

var x = _context.GameHasPlayers.Join(_context.Games, e => new { playerId = e.PlayerId, gameId = e.GameId }, y => new { playerId, gameId = y.Id }, (e, y) => new Game{ });

两个查询都将转换为相同的sql查询。