2012-01-02 93 views
0

我有一個EF模型有3個表,Artist,MovieMovie_Artist_JobMovie_Artist_Job只是一個外鍵表:複雜的LINQ到實體查詢

MovieId,ArtistId,JobId. 

我試圖讓一個結果是這樣的:

ArtistName1,劇場1

ArtistName1,電影2

Artistname2,劇場1

Artistname2,Movie3

等等

現在我這樣做:

var query = (
    from items in _objEntities.Movie_Artist_Job 
    where items.Artist.FulleName != string.Empty 
    select items.Artist.FulleName).Distinct<string>(); 

List<ThumbItem> Items = new List<ThumbItem>(); 

foreach (string fullName in query) 
{ 
    var matching = (
     from movie in _objEntities.Movie_Artist_Job 
     where movie.Artist.FulleName == fullName 
     select movie.Movie) 
     .Distinct<Movie>(); 

    if (matching.Count() > 0) 
    { 
     foreach (Movie movies in matching) 
     { 
      if (movies != null && movies.IsDeleted == false) 
      { 
       new ThumbItem(fullName, movies.title); 
      } 
     } 
    } 
} 

它的工作原理,但它需要年齡...

如何樂觀中任何線索?

非常感謝你的幫助。

+0

你試過分析這個?您可以使用SQL事件探查器找出在封面下執行的查詢。我敢打賭,1.太多的查詢被執行,2.你缺少一些數據庫索引。 – Steven 2012-01-02 12:31:47

回答

0

我試圖複製DB你所提到的: -

  1. 藝術家
  2. 電影
  3. 喬布斯

和我添加一個實體類thumbItem如下;選擇項目: -

internal class ThumbItem 
{ 
    public string ArtistName { set; get; } 
    public string MovieName { set; get; } 
} 

,我已經進行了下面的函數來得到你要求的結果: -

MoviesEntities context = new MoviesEntities(); 

     var Thumbs = from artist in context.Artists 
        join job in context.Jobs on artist.ID equals job.ArtistID 
        join movie in context.Movies on job.MovieID equals movie.ID 
        select new ThumbItem() 
           { 
            ArtistName = artist.Name, 
            MovieName = movie.Name 
           }; 


     dataGridView1.DataSource = Thumbs; 

它的工作速度非常快,並沒有採取任何東西,我覺得你的問題你是否將匹配和控件的創建分成了不同的步驟,而不是使用select into entity來執行連接語句;這是耗時的行動。

編輯: -

新問題的評論: - 需要每個藝術家的電影的數量從相同的查詢?

只是一前一後添加此代碼之前,它會得到你DB往返結果: -

var ListByArtist = Thumbs.ToList().GroupBy(l => l.ArtistName).Select(lg => new 
         { 
          Artist = lg.Key, 
          NumberOfMovies = lg.Count() 
         }); 
+0

你好OmarQa,你的代碼巖:)謝謝你的快速幫助。有沒有機會使用您的查詢獲取每位藝術家的電影數量? – myCollections 2012-01-02 14:38:01

+0

嗨,感謝您的補充,您可以通過從拇指項目列表中選擇一個分組計數來獲得每位藝術家的電影數量,我編輯了我的答案,您可以檢查它,希望這是您所需要的,祝您好運:) – oqx 2012-01-02 22:36:06

+0

非常感謝您的幫助。 – myCollections 2012-01-03 10:21:52

0

你正以一種尷尬的方式處理很多很多關係。更簡單的方法將是有這個表作爲與主鍵

public class Movie_Artist_Job 
{ 
    public int Id { get; set; } 
    public Artist Artist { get; set; } 
    public Movie Movie { get; set; } 
} 

然後下面,只需撥打db.Movie_Artist_Job.ToList()

+0

同意你的方法,但我不先使用代碼,所以我必須管理現有的Db模式。 – myCollections 2012-01-02 12:35:57

2

您查詢循環中的數據庫。這導致N + 1個查詢。嘗試重寫代碼以下:

var query = (
    from items in _objEntities.Movie_Artist_Job 
    where items.Artist.FulleName != string.Empty 
    select items.Artist.FulleName) 
    .Distinct(); 

var matching = 
    from fullName in query 
    from movie in _objEntities.Movie_Artist_Job 
    where movie.Artist.FulleName == fullName 
    where !movies.IsDeleted 
    select new { movie.fullName, movie.title }) 
    .Distinct() 
    .ToArray(); 

List<ThumbItem> Items = (
    from movie in matching 
    select new ThumbItem(movie.fullName, movie.title)) 
    .ToList(); 
+0

感謝您的代碼,但OmarQa的答案非常快。 BTW非常感謝您花時間幫助我。 – myCollections 2012-01-02 14:39:25

0

你所試圖做的是所謂的「旋轉」,你應該如何實現這一目標上正確地構建EF模型一看Linq Extensions Library

作爲一個注意事項,EF的所有要點都是能夠以自然的面向對象的方式編寫查詢,也就是說,您不應該在意C#方面的「Movie_Artist_Job」表格(Calling Artist 。電影應該返回給定的藝術家的電影列表)