【问题标题】:How to create LINQ query to show all movies only once?如何创建 LINQ 查询以仅显示所有电影一次?
【发布时间】:2017-04-19 23:25:50
【问题描述】:

我有 3 个表,为简单起见,我将使用 IMDB 示例(用户评分电影)。

  • 表 1:电影
  • 表 2:MovieUserRating
  • 表 3:用户。

电影(3 部电影):

ID  MOVIE_NAME  
1   Movie1  
2   Movie2  
3   Movie3  

MovieUserRating(两个用户都只评价了电影 1):

MOVIE_ID    USER_ID RATING  
1             1       10  
1             2        9  

用户(2 个用户):

ID  USER_NAME  
1   User1  
2   User2  

因此,如果有任何用户登录(例如 User1),我需要执行 LINQ 查询,该查询将返回所有电影的列表和记录的用户对它们的评分。如果电影没有被登录用户评分,它将显示 0。

所以,我需要这样的结果(如果 user1 已登录):

MOVIE       RATING  
Movie1        10  
Movie2         0  

如果 user2 已登录:

MOVIE       RATING  
Movie1        9  
Movie2        0  

所以,这是我在 ASP.NET 控制器中的查询(不好):

var results =   
    from m in db.Movies  
    from mur in db.MoveUserRatings.Where( mur => mur.MOVIE_ID == m.ID).DefaultIfEmpty()  
    from u in db.Users.Where( u=>u.ID == mur.USER_ID).DefaultIfEmpty()  
        select new MyModelViewClass  
        {  
            MovieName = m.MOVIE_NAME,         
            MovieRating = (u.Id == “user ID that was supplied”) ? mur.RATING : 0  
        };  

不幸的是,此查询返回 Movie1 两次,因为它已被两个用户评分。因此,结果如下所示:

(如果用户 1 已登录):

MOVIE       RATING  
Movie1        10  
Movie1         0  
Movie2         0  

(如果 2 已登录):

MOVIE       RATING  
Movie1        9  
Movie1        0  
Movie2        0  

如何解决此问题以获得所需的结果(电影 1 仅放映一次)?

提前感谢您的帮助。

【问题讨论】:

标签: c# entity-framework linq join distinct-values


【解决方案1】:

您的查询不会按登录用户过滤结果,而只会更改所选值。你可以试试这个:

var results =
   from m in db.Movies
   join mur in db.MoveUserRatings.Where(k=> k.USER_ID == “user ID that was supplied”) on m.ID equals mur.MOVIE_ID into murs
   from mmur in murs.DefaultIfEmpty()
   select new MyModelViewClass
   {
       MovieName = m.MOVIE_NAME,
       MovieRating = mmur.RATING ?? 0
   };

注意:'??'类似于 SQL COALESCE 运算符。

【讨论】:

  • 您还可以使用匿名类型在on 子句上设置过滤器以检查IDUSER_ID
  • 其他人讨厌语法如何导致您为连接实体拥有 3 个别名,例如 murmursmmur
  • @ChrisMoutray 不过没必要 - 我不知道为什么人们倾向于使用不同的别名。在into 子句之后,mur 范围变量超出范围,因此可以使用它来代替mmur
  • @ChrisMoutray 我知道这是一堆乱七八糟的别名,但我认为这对于初学者来说会更明确(他们不知道范围,我会模棱两可)。
  • @Ivan 啊,谢谢,不明白你可以重用别名 - 我最近一直坚持使用方法语法而不是查询语法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 2019-03-30
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
相关资源
最近更新 更多