2016-01-16 66 views
0

我有以下方法:LINQ的联盟操作

public IList<Book> Search(IList<int> genre) 
{  
    IQueryable<Book> books = database.Books; 
    if (genres.Count > 0) 
    { 
     books = books.Include("Genres"); 
     foreach (int genreId in genres) 
     { 
      books = books.Union(books.Where(b => b.Genres.Any(g => g.Id == genreId))); 
     } 
    } 
    return books.ToList() 
} 

其停止在最后一行的工作。为什么?也许有人知道更有效的方式来获得属于相应类型ID的所有实体?

+1

你是什么意思由停止工作?该查询在那个时间点被解析,所以如果查询花费太长时间,它将一直呆在那里,直到结果准备就绪。为了更好地实现'.Contains' –

+0

如果你的意思是下一行在调试时不会运行,请在它之间放一个'try catch'并获取异常消息以查看错误 –

+0

它显示什么错误? –

回答

2

我认为你应该以相反的方式去做。即,从风格到书籍是这样的:

return 
    database 
    .Genres 
    .Where(g => genre.Contains(g.Id)) 
    .SelectMany(g => g.Books) 
    .ToList(); 

此代码假定存在是去从GenreBook这样的导航属性:

public class Genre 
{ 
    public Genre() 
    { 
     Books = new HashSet<Book>(); 
     //... 
    } 

    public virtual ICollection<Book> Books {get;set;} 
    //... Other properties here 
} 
0
public class Test 
{ 

    private List<Book> books = new List<Book>() 
    { 
     new Book 
     { 
      Id = 1, 
      Genres = new List<Genre>() 
      { 
       new Genre 
       { 
        Id = 1 
       }, 
       new Genre 
       { 
        Id = 2 
       } 
      } 
     }, 
     new Book 
     { 
      Id = 2, 
      Genres = new List<Genre>() 
      { 
       new Genre 
       { 
        Id = 3 
       } 
      } 
     } 
    }; 

    public IList<Book> Search(IList<int> genres) 
    { 

     return books.Where(x => x.Genres.Any(y => genres.Contains(y.Id))).ToList(); 

    } 

} 

做了一个简单的例子。在函数中,Search只能用database.Books替换书。

测试验证结果。

[TestClass] 
public class UnitTest1 
{ 

    Test t; 

    [TestInitialize] 
    public void TestInitialize() 
    { 
     t = new Test(); 
    } 

    [TestMethod] 
    public void TestGetBooksByGenre() 
    { 
     var result = t.Search(new List<int>() 
     { 
      1 
     }); 

     Assert.IsTrue(result.Count == 1); 
     Assert.IsTrue(result[0].Id == 1); 
    } 
}