2010-11-08 4 views
1

Compte tenu des deux collections distinctes suivantes:requête LINQ pour trouver des chaînes communes entre deux collections

IQueryable<Book> allBooks = context.Books.Where(b => b.UserID == hostID); 

var visBookTitles = context.Books.Where(b => b.UserID == visitorID) 
.Select(b =>b.Title.ToLower()).ToList(); 

Quelle serait la façon la plus efficace (en utilisant la syntaxe de la méthode, de préférence) pour renvoyer tous les livres de allBooks qui partagent une titre commun avec l'un des titres de visBookTitles?

Répondre

1

Comme ceci:

var bookTitles = new HashSet<string>(visBookTitles, StringComparer.OrdinalIgnoreCase); 
var someBooks = allBooks.AsEnumerable().Where(b => bookTitles.Contains(b.Title)); 

Vous devriez également vous débarrasser de l'appel ToLower. (StringComparer.OrdinalIgnoreCase est plus rapide et gère les situations Unicode malpropres)

+0

Avez-vous besoin de 'AsEnumerable()'? Vous ne pouvez pas utiliser l'extension 'Where' sur' IQueryable '? – RPM1984

+0

@RPM: Je suppose qu'il utilise LINQ to SQL ou EF, auquel cas l'utilisation de 'IQueryable ' lancerait une exception car il ne peut pas être traduit en SQL. – SLaks

+0

Ahh, k - assez bien. Figuré c'était des objets LINQ réguliers. – RPM1984

2

Utilisez Intersect() si les éléments des collections doivent être considérés comme égaux ou Join() s'ils ne partagent que certaines propriétés. Dans votre cas, vous recoupez des livres par rapport à des titres, donc Join() est le plus approprié.

var query = allBooks.Join(visBookTitles, 
          book => book.Title, 
          title => title, 
          (book, title) => book); 
Questions connexes