2017-04-19 11 views
1

私は3つのテーブルを持っていますが、わかりやすくするために、IMDBの例(ムービー評価ユーザー)を使用します。LINQクエリを作成してすべてのムービーを1回だけ表示する方法はありますか?

  • 表1:映画
  • 表2:ユーザー:
  • 表3 MovieUserRating。

ムービー(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クエリを実行して、すべてのムービーの一覧とログされたユーザーの評価を返します。ムービーがログインしているユーザーによって評価されていない場合、それは(user1がログインしている場合)は0

だから、私はこのように見える結果が必要に表示されるでしょう:

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 
     }; 

、このクエリretur両方のユーザーによって評価されているので、ns Movie1を2回繰り返します。

(ユーザ1がログインしている場合):

(2がログインしている場合):

MOVIE  RATING 
Movie1  9 
Movie1  0 
Movie2  0 

がどのように私は結果を得るために、この問題を解決することができますので、この結果は次のようになり私は必要です(映画1は1回だけ表示されます)?

ご協力いただきありがとうございます。

+0

あなたのエントリに 'join'する必要がありますhttp://stackoverflow.com/q/5537995/81053 –

答えて

2

あなたのクエリは、ログインしたユーザによる結果をフィルタリングするのではなく、選択した値を変更するだけです。これを試すことができます:

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演算子に似ています。

+1

' on'節でフィルタを設定し、匿名型を使って 'ID'と' USER_ID' – bradbury9

+0

他の誰かが、結合されたエンティティの3つのエイリアス(例えば、mur'、 'murs'、' mmur')をもたらす方法を嫌います。 –

+1

@ChrisMoutrayそれは必要ではありません。エイリアス。 'into'節の後、' mur'の範囲変数は範囲外です。したがって 'mmur'の代わりに使用することができます。 –

関連する問題