2013-01-11 3 views
5

J'ai deux tables, chacun avec leur propre modèle ...correspondants deux listes de différents types ensemble

class FamilyMan 
    { 
     public int family_ID {get; set;} 

     public string name {get; set;} 
     public string fav_color {get; set;} 
    } 

    class BusinessMan 
    { 
     public int work_ID {get; set;} 

     public string name {get; set;} 
     public string fav_color {get; set;} 

     //unrelated data etc 
     public string job_title {get; set;} 
    } 

... et je veux être en mesure de faire correspondre tous FamilyMans aux businessmans correspondants basés sur name et fav_color.

J'ai actuellement quelque chose comme:

//fill lists from database 
    var family_list = dbContext.FamilyMen.ToList(); 
    var busy_list = dbContext.BusinessMen.ToList(); 
    //create empty dict for matching the two types 
    var matches = new Dict<FamilyMan, BusinessMan>(); 


    foreach (FamilyMan fam_man in family_list) { 
     foreach (BusinessMan busy_man in busy_list) { 
      //if both names and colors match, consider them a matching 
      //object and add them each to the dict 
      if (fam_man.name == busy_man.name && 
        fam_man.color == busy_man.color) { 
       matches_MtO[fam_man] = busy_man; 
      } 
     } 
    } 

mais il faut un certain temps pour terminer.

J'ai également regardé en boucle sur une liste avec un foreach, puis en utilisant LINQs FirstOrDefault pour les faire correspondre, mais l'efficacité semble à peu près la même.

Existe-t-il une meilleure façon d'associer FamilyMan s et BusinessMan s?

Répondre

3

Vous devez utiliser la syntaxe de se joindre à LINQ. Cela permettra à la base de données dorsale de faire la correspondance, et ne retournera que le résultat.

Afin de permettre une jointure sur une clé composée, suivez la MSDN guidance here.

var query = from fm in dbContext.FamilyMen 
      join bm in dbContext.BusinessMen on 
       new { bm.name, bm.color } equals new { fm.name, fm.color } 
      select new { 
       FamilyMan = fm, 
       BusinessMan = bm 
      }; 

var resultList = query.ToList(); 
+0

J'ai dû ajouter des noms correspondants aux deux premiers objets anonymes,' Name' et 'Color', respectivement, et cela a semblé fonctionner instantanément. Cela fonctionne très bien, je vais donner à @Gerve une minute pour corriger sa requête afin de résoudre le problème 'Expression Expected' si c'est possible, sinon j'accepterai cette réponse. Merci! – TankorSmash

+0

"noms correspondants" étant quelque chose comme 'new {Name = nom_bm, Color = bm.color}' pour les deux objets. À partir des documents que vous avez liés: 'Par exemple, si la table Orders et la table OrderDetails utilisent chacune des noms différents pour leurs colonnes, vous pouvez créer des clés composées en attribuant des noms identiques aux types anonymes:' Merci encore! – TankorSmash

2

Vous parcourez les deux listes, c'est-à-dire O (N-carré).

Une fois qu'un élément est apparié, il ne doit pas être à nouveau associé. Vous pouvez supprimer les éléments correspondants de la liste, ce qui réduit les comparaisons inutiles.

Mieux encore, puisque vous faites correspondre deux propriétés identiques, vous pouvez créer un dictionnaire en utilisant un hachage représentant les propriétés combinées en tant que clé. Ensuite, vous pouvez parcourir les clés de family_list_dictionary et simplement rechercher une clé correspondante dans busy_list_dictionary.

+0

Je ne l'ai jamais travaillé avec hash avant, vous avez des bons exemples désinvolture? Serais-je en boucle dans les deux tables, tirant les deux propriétés, les convertir en un hachage en quelque sorte, enregistrer le hachage à une liste, puis passer par la liste de hachage et de comparer les hachages de la famille aux hachages d'affaires? – TankorSmash

+0

Je ne suis pas devant un ordinateur en ce moment. Je peux vous donner un exemple détaillé dans quelques heures. –

+0

Ne vous inquiétez pas à ce sujet, si vous ne voulez pas, j'ai trouvé une réponse de travail http://stackoverflow.com/a/14283717/541208. Je voudrais apprendre à faire quelque chose comme ça, mais pas de soucis. – TankorSmash

4

Est-ce que une requête LINQ comme ceci plus rapide:

var matches = (
    from f in family_list 
    join b in busy_list 
    on f.color == b.color 
    && f.name == b.name 
    select new {f, b} 
); 
+0

après '... == b.color' le '&&' ne semble pas fonctionner. 'Expression Expected' – TankorSmash

Questions connexes