2013-01-11 20 views
5

Mam dwie tabele, każdy z własnym modelem ...Dopasowany dwie listy różnych typów wraz

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

... i chcę, aby być w stanie dopasować się do wszystkich FamilyMans Businessmans pasujące na podstawie name i fav_color.

Obecnie mam coś takiego:

//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; 
      } 
     } 
    } 

ale zajmuje sporo czasu, aby zakończyć.

Zajrzałem również do pętli nad jedną listą z foreach, a następnie za pomocą LINQs FirstOrDefault, aby je dopasować, ale wydajność wydaje się mniej więcej taka sama.

Czy istnieje lepszy sposób na dopasowanie do FamilyMan s i BusinessMan s razem?

Odpowiedz

3

Należy użyć składni LINQ za przyłączenia. Umożliwi to bazy danych zaplecza zrobić dopasowanie i zwraca tylko wynik.

W celu umożliwienia sprzężenia na kluczu złożonym przed śledzić 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

Musiałem dodać pasujące nazwy do dwóch pierwszych anonimowych obiektów, odpowiednio" Nazwa "i" Kolor ", i wydawało się, że działają natychmiast. To działa bardzo dobrze, po prostu daję @Gerve minutę, aby naprawić swoje zapytanie, aby rozwiązać problem z wyrażeniem "Expression Expected", jeśli jest to możliwe, inaczej przyjmuję tę odpowiedź. Dzięki! – TankorSmash

+0

"Nazwy pasujące" to coś takiego jak "nowe {Nazwa = nazwa_bł., Kolor = bm.kolor}" dla obu obiektów. Z połączonych dokumentów: 'Na przykład, jeśli tabela Zamówienia i Tabela Zamówień zamówień używają różnych nazw dla swoich kolumn, można utworzyć klucze złożone, przypisując identyczne nazwy w anonimowych typach:' Jeszcze raz dziękuję! – TankorSmash

2

Twoje pętle przechodzą przez obie listy, czyli O (N-kwadrat).

Po dopasowaniu elementu, nie trzeba go ponownie dopasowywać. Możesz usunąć dopasowane elementy z listy, zmniejszając niepotrzebne porównania.

Co więcej, ponieważ dopasowujesz dwie właściwości, które są identyczne, możesz zbudować słownik, używając skrótu reprezentującego połączone właściwości jako klucz. Następnie możesz przechodzić przez klawisze rodziny_list_dictionary i po prostu szukać pasującego klucza w busy_list_dictionary.

+0

nigdy nie pracował z mieszań, masz jakieś dobre przykłady bezceremonialny? Czy przejdę przez obie tabele, wyciągając dwie właściwości, konwertując je do mieszania w jakiś sposób, zapisując hasz do listy, a następnie przejdę przez listę haszującą i porównam rodzinne skróty do biznesowych skrótów? – TankorSmash

+0

Nie jestem teraz na komputerze. Mogę podać dokładny przykład za kilka godzin. –

+0

Nie martw się, jeśli nie chcesz, znalazłem działającą odpowiedź http://stackoverflow.com/a/14283717/541208. Chciałbym nauczyć się, jak to zrobić, ale nie martw się. – TankorSmash

4

Czy kwerendy LINQ jak to będzie szybciej:

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

po '... == b.color' the '&&' wydaje się nie działać. 'Expression Expected' – TankorSmash