2010-08-31 3 views
3

Je trouve toujours que je crée des expressions linq qui utilisent encore fortement les boucles foreach imbriquées. Voici un exemple simple de ce dont je parle, et j'apprécierais vraiment si quelqu'un ici peut me montrer comment condenser ce code à faible efficacité en une seule expression linq?Se débarrasser des boucles foreach imbriquées lors de l'utilisation de linq

Le contexte de base de données (db) comporte trois tables: Blog, Tag, Junc_Tag_Blog. La table de jonction enregistre simplement un enregistrement de blogs avec leurs tags.

Quoi qu'il en soit, voici mon code désordre:

public static Collection<Blog> GetByTag(string tagName) 
{ 
    // Get the tag record. 
    var tag = (from t in db.Tags 
       where t.Name == tagName 
       select t).Single(); 

    // Get the list of all junction table records. 
    var tagJunc = from tj in db.Junc_Tag_Blogs 
        where tj.Fk_Tag_Id == tag.Id 
        select tj; 

    // Get a list of all blogs. 
    var blogs = from b in db.BlogPosts 
       select b; 

    // Work out if each blog is associated with given tag. 
    foreach(var blog in blogs) 
    { 
     foreach(var junc in tagJunc) 
     { 
      if(blog.Id == junc.Fk_Blog_Id) 
      { 
       // We have a match! - do something with this result. 
      } 
     } 
    } 
} 

Merci à l'avance à la personne qui peut me aider à nettoyer cette place de code!

Répondre

4

Vous pouvez construire une requête qui permet à la base de données de trouver les correspondances pour vous.

List<Blog> blogs = 
(
    from t in tag 
    where t.Name == tagName 
    from tj in t.Junc_Tag_Blogs 
    let b = tj.Blog 
    select b 
).ToList(); 
0

Vous pouvez mettre les blogs dans un dictionnaire, groupe les jonctions sur l'ID de blog, et boucle à travers les groupes:

var blogDict = blogs.ToDictionary(b => b.Id); 

foreach(var group in tagJunk.GroupBy(j => j.Fk_Blog_Id)) { 
    if (blogDict.ContainsKey(group.Key)) { 
    var blog = blogDict[group.Key]; 
    foreach (var junction in group) { 
     // here you have the blog and the junction 
    } 
    } 
} 

Ceci est également boucles imbriquées, mais pour chaque blog que vous ne boucle à travers les jonctions qui appartiennent réellement à ce blog, au lieu de toutes les jonctions.

1
var blogsWithGivenTag = 
    from blog in db.BlogPosts 
    where blog.BlogTags.Any(bt => bt.Tag.Name == tagName) 
    select blog; 
Questions connexes