2016-08-02 157 views
0

我正在製作電影數據庫webapp,但我不知道如何使用多對多進行搜索,如果我想要按照流派搜索電影,我該怎麼做?以及如何使實體framwork搜索流派的流派數量,就像我可以搜索1,2或更多的流派。像過濾。實體框架多對多搜索

這是我走到這一步,

var query = from movie in db.Movies where movie.Genres.Any(g => g.GenreID == 2) select movie; 

g.GenreID = 2目前硬編碼的,但如何使其接受GenreID搜索?我嘗試g => g.GenreID == 2 && g.GenreID == 3,但它不返回任何電影。當兩個條件都成立時我怎樣才能讓它返回電影?

這是我的桌子,底部是我想要完成的。

Movie 
--------------------------- 
MovieID MovieTitle 
1  The GodFather 
2  Analyze This 
3  The GodFather Part II 

Genre 
--------------------------- 
GenreID GenreName 
1  Comedy 
2  Crime 
3  Drama 

MovieGenre 
--------------------------- 
MovieID GenreID 
1  2   // The GodFather -- Crime, Drama 
1  3   // 
2  1   // Analyze This -- Comedy, Crime 
2  2   // 
3  2   // The GodFather Part 2 -- Crime, Drama 
3  3   // 


Result 
--------------------------- 
Search: Drama 
Result: The GodFather, The GodFather Part II 

Search: Comedy 
Result: Analyze This 

Search: Crime 
Result: The GodFather, Analyze This, The GodFather Part II 

Search: Crime, Drama 
Result: Result: The GodFather, The GodFather Part II 

Search: Crime, Drama, Comedy 
Result: none 

這裏是我的模型和上下文

Movie.cs 

public class Movie 
{ 
    public int MovieID { get; set; } 
    public string MovieTitle { get; set; } 

    public virtual ICollection<Genre> Genres { get; set; } 
} 


Genre.cs 

public class Genre 
{ 
    public int GenreID { get; set; } 
    public string GenreName { get; set; } 

    public virtual ICollection<Movie> Movies { get; set; } 
} 


AppDbContext.cs 

public class AppDbContext : DbContext 
{ 
    public AppDbContext() : base("MovieConnection") 
    { 
    } 

    public DbSet<Movie> Movies { get; set; } 
    public DbSet<Genre> Genres { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
    } 
} 

回答

0

試試這個:

var genreIds = new List<int> { 2, 3 }; 

using (var db = new YourContext()) 
{ 
    var movies = db.Movies; 

    foreach (var genreId in genreIds) 
    { 
     movies = movies.Where(m => m.Genres.Any(g => g.GenreID == genreId)); 
    } 

    var queryResults = movies.ToList(); 
} 
+0

它的工作,但我需要更多的測試。有一些關於var電影的小修改,所以我將它改爲IQueryable 電影。謝謝,我一直在尋找幾個小時。 – markoverflow

1

您可以通過使用「或」條件這樣g => g.GenreID == 2 || g.GenreID == 3

「與」在g => g.GenreID == 2 && g.GenreID == 3條件意味着它將返回記錄同時具有genreid 2和3.單個記錄不能有多個genreid。

如果需要返回既有genreid的, 你需要基本的查詢是這樣的

select MovieID 
    from MovieGenre 
where GenreID in(244,246) 
group 
    by MovieID 
having count(*) = 2 ; 

「2」的電影是類型ID的passing.Change的數量這成相應的LINQ

Linq可能是這樣的。這個linq未經測試,可能包含錯誤

var query = from movie in db.Movies 
       where movie.Genres.Any(g => g.GenreID == 2|| g.GenreID == 3) 
       group movie by movie.MovieID into m 
       where m.Count() == 2 
       select movie.MovieID 
+0

我可以不使用或。我想要的是返回包含這些流派的電影。就像我搜索2和3 genreID,它會返回一個有這些類型的電影。 – markoverflow

+0

參考更新的答案 –

+0

我得到的想法,我認爲這也會工作,但即時通訊有問題,當我通過movie.MovieID添加到組的電影m其中m.Count()== 2 **它給語法錯誤名稱'movie'在當前上下文中不存在。它使最後一部分選擇電影波浪線。電影ID – markoverflow

0

您是混合方法與查詢語法。 也許這個作品

var Movies = db.Movies.Where(m => m.Genres.Any(g => g.GenreID == 2).FirstOrDefault()).ToList(); 
+0

但如果我搜索多個genreID?它拋出'布爾'不包含定義; FirstOrDefault' – markoverflow

0

所以,如果2和3被選中,將返回的是電影流派2或3

public ActionResult Search(IEnumerable<int> selectedGenreIds) 
{ 
    var moviesInSelectedGenres = db.Genres.Where(x => selectedGenreIds.Any(z => z == x.GenreId)).Select(x => x.Movies); 
} 
+0

這並不能解決我的問題,但是,謝謝,我想要的是讓我們說一部電影稱爲教父有2和3的風格,和另一部電影喜歡分析這個有流派的1和3,所以如果我搜索genreID 3,它會返回兩個電影,但如果我搜索,genreID 2,它會返回教父,然後如果我搜索genreID 1和3,它只會返回電影分析一下。我想要實現的是某種過濾。 – markoverflow