2012-01-02 119 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 。电影应该返回给定的艺术家的电影列表)