2013-12-10 11 views
9

Mam tabeli w następujący sposób:Czy mogę dołączyć do tabeli do listy przy użyciu linq?

PersonalDetails 

Columns are: 

Name 
BankName 
BranchName 
AccountNo 
Address 

mam inną listę, która zawiera 'nazwa' i 'AccountNo'. Muszę znaleźć wszystkie zapisy z tabeli, których odpowiednie "Nazwa" i "Konto" są obecne na podanej liście.

Wszelkie sugestie będą pomocne.

Zrobiłem następujący ale nie stanowi większego użytku:

var duplicationhecklist = dataAccessdup.MST_FarmerProfile 
          .Join(lstFarmerProfiles, 
           t => new { t.Name,t.AccountNo}, 
           t1 => new { t1.Name, t1.AccountNo}, 
           (t, t1) => new { t, t1 }) 
          .Select(x => new { 
               x.t1.Name, 
               x.t1.BankName, 
               x.t1.BranchName, 
               x.t1.AccountNo 
              }).ToList(); 

gdzie lstFarmerProfiles jest lista.

+0

A może pokażesz nam, co zrobiłeś pierwszy? – gleng

+0

@gleng: ok. Redagowanie. – Saket

+0

@gleng: Teraz możesz pomóc? – Saket

Odpowiedz

16

Prawdopodobnie odkryłeś, że nie możesz dołączyć do kwerendy LINQ Entity Framework z lokalną listą obiektów encji, ponieważ nie można jej przetłumaczyć na SQL. Wcześniej wybiorę dane z bazy danych tylko na numery kont, a następnie dołączę do pamięci.

var accountNumbers = lstFarmerProfiles.Select(x => x.AccountNo).ToArray(); 

var duplicationChecklist = 
     from profile in dataAccessdup.MST_FarmerProfile 
            .Where(p => accountNumbers 
                .Contains(p.AccountNo)) 
            .AsEnumerable() // Continue in memory 
     join param in lstFarmerProfiles on 
      new { profile.Name, profile.AccountNo} equals 
      new { param.Name, param.AccountNo} 
     select profile 

Więc nigdy nie będzie ciągnąć dane do pamięci masowych, ale najmniejszy wybór prawdopodobnie można kontynuować.

Jeśli accountNumbers zawiera tysiące elementów, możesz rozważyć użycie lepszego skalowalnego chunky Contains method.

+0

Otrzymuję następujący wyjątek: "Odwołanie do obiektu nie jest ustawione na wystąpienie obiektu." – Saket

+0

Występuje po wykonaniu drugiego zapytania. Źródłem jest 'FarmerProfiling', a lstFarmerProfiles jest listą tego modelu. – Saket

+0

Działało z kilkoma modyfikacjami. Dzięki! – Saket

0

Skoro masz list w .NET wartości chcesz znaleźć, spróbuj użyć metody Contains, dla próbki:

List<string> names = /* list of names */; 
List<string> accounts = /* list of account */; 

var result = db.PersonalDetails.Where(x => names.Contains(x.Name) && accounts.Contains(x.AccountNo)) 
           .ToList(); 
+0

Istnieje jedna lista, która ma nazwy i konta. – Saket

+0

Czy nie możesz oddzielić go na dwie listy, tak jak pokazuję ?! –

+0

Nie będzie pasować do każdego rekordu bazy danych dokładnie do każdego wiersza listy. – Saket

2

Jeśli MST_FarmerProfile nie jest bardzo duży, myślę, że najlepszym rozwiązaniem jest doprowadzenie do pamięci za pomocą AsEnumerable() i do łączenia tam.

var duplicationhecklist = 
      (from x in dataAccessdup.MST_FarmerProfile 
         .Select(z => new { 
              z.Name, 
              z.BankName, 
              z.BranchName, 
              z.AccountNo 
              }).AsEnumerable() 
       join y in lstFarmerProfiles 
       on new { x.Name, x.AccountNo} equals new { y.Name, y.AccountNo} 
       select x).ToList(); 
+0

MST_FarmerProfile zawiera 2 miliony rekordów. Czy nadal będziesz sugerować to samo? – Saket

+0

@sake Być może nie trzeba wprowadzać wszystkich kolumn ze stołu do pamięci, należy dokonać wyboru przed '.AsEnumerable()', aby uzyskać potrzebne kolumny. Jedynym sposobem sprawdzenia, czy czas wykonania jest akceptowalny, jest przetestowanie go. – Magnus

+0

@Setet Jak duże jest 'lstFarmerProfiles'? – Magnus

0

Jeśli accountNo identyfikuje rekord następnie można użyć:

var duplicationCheck = from farmerProfile in dataAccessdup.MST_FarmerProfile 
         join farmerFromList in lstFarmerProfiles 
         on farmerProfile.AccountNo equals farmerFromList.AccountNo 
         select new { 
             farmerProfile.Name, 
             farmerProfile.BankName, 
             farmerProfile.BranchName, 
             farmerProfile.AccountNo 
            }; 

Jeśli chcesz dołączyć imię i nazwisko oraz numer konta to powinno działać:

var duplicationCheck = from farmerProfile in dataAccessdup.MST_FarmerProfile 
         join farmerFromList in lstFarmerProfiles 
         on new 
         { 
          accountNo = farmerProfile.AccountNo, 
          name = farmerProfile.Name 
         } 
         equals new 
         { 
          accountNo = farmerFromList.AccountNo, 
          name = farmerFromList.Name 
         } 
         select new 
         { 
          farmerProfile.Name, 
          farmerProfile.BankName, 
          farmerProfile.BranchName, 
          farmerProfile.AccountNo 
         }; 

Jeśli tylko będzie aby przejść przez duplicateChecklist raz, a następnie wyjście .ToList() będzie lepiej dla wydajności.

Powiązane problemy