2016-08-02 108 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