2016-01-16 3 views
0

У меня есть следующий метод:Linq Union Оператор

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() 
} 

Он останавливается, чтобы работать на последней строке. Зачем? Может быть, кто-то знает более эффективный способ получить все сущности, которые принадлежат соответствующему идентификатору жанра?

+1

Что вы подразумеваете под остановкой на работу? Запрос разрешен в этой точке, поэтому, если запрос занимает слишком много времени, он останется там до тех пор, пока результаты не будут готовы. Для лучшего способа сделать это загляните в '.Contains' –

+0

Если вы имеете в виду, что следующие строки не будут выполняться при отладке, поместите« try catch »между ним и получите сообщение об ошибке, чтобы увидеть ошибку –

+0

, какую ошибку она показывает ? –

ответ

2

Я думаю, что вы должны сделать это наоборот. Т.е., перейти от жанра к книгам, как это:

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

Этот код предполагает, что есть навигационное свойство, которое идет от Genre к Book как это:

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(); 

    } 

} 

Сделан быстрый пример. В функции Искать только заменить книги на базу данных.

Проверка результатов проверки.

[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); 
    } 
}