web-dev-qa-db-fra.com

Puis-je joindre une table à une liste en utilisant linq?

J'ai une table comme suit:

PersonalDetails

Columns are:

Name  
BankName
BranchName
AccountNo
Address

J'ai une autre liste qui contient 'Nom' et 'CompteNo' . Je dois trouver tous les enregistrements de la table dont la 'Nom' et le 'CompteNo' sont présents dans la liste donnée 

Toute suggestion sera utile.

J'ai fait suivre mais pas beaucoup d'utilisation:

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();

lstFarmerProfiles est une liste.

12
Saket

Vous avez probablement découvert que vous ne pouvez pas joindre une requête LINQ Entity Framework avec une liste locale d'objets d'entité, car elle ne peut pas être traduite en SQL. Je présélectionnerais les données de la base de données sur les numéros de compte seulement, puis les joindrais en mémoire.

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

Ainsi, vous ne tirerez jamais dans la mémoire les données en vrac, mais la plus petite sélection possible.

Si accountNumbers contient des milliers d’éléments, vous pouvez envisager d’utiliser une meilleure méthode évolutive chunky Contains .

18
Gert Arnold

Si MST_FarmerProfile n'est pas très gros, je pense que la meilleure option est de le mettre en mémoire à l'aide de AsEnumerable() et de faire la jonction à cet endroit.

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();
2
Magnus

Puisque vous avez les listes en .net de valeurs que vous voulez trouver, essayez d’utiliser la méthode Contains, par exemple:

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();
2
Felipe Oriani

Si accountNo identifie l'enregistrement, vous pouvez utiliser:

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

Si vous devez joindre un nom et un compte, cela devrait fonctionner:

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

Si vous ne parcourez qu'une seule fois la liste de contrôle duplicate, le fait de laisser .ToList () en sortie sera plus performant.

0
Bvrce

Étant donné que les données se trouvent généralement sur différentes machines ou au moins dans des processus distincts: DB - en est une et votre liste en mémoire est votre application, il n'y a que 2 façons de le faire. 

  1. Téléchargez sous forme de petite partie de données de la base de données vers le plus local possible et joignez-vous localement (généralement à l'aide de AsEnumerable() ou fondamentalement ToList()). Vous avez beaucoup de bonnes pensées à ce sujet dans d'autres réponses.
  2. Une autre est différente - téléchargez vos données locales sur le serveur d’une manière ou d’une autre et effectuez une requête côté DB. Le téléchargement peut être effectué différemment: en utilisant des tables temporaires OR en utilisant VALUES. Heureusement, il existe maintenant une petite extension pour EF (pour EF6 et EF Core) que vous pouvez essayer. Il s’agit de EntityFrameworkCore.MemoryJoin (le nom peut prêter à confusion, mais il prend en charge EF6 et EF Core). Comme indiqué dans l'auteur article , il modifie la requête SQL transmise au serveur et injecte la construction VALUES ​​ avec les données de votre liste locale. Et la requête est exécutée sur le serveur de base de données.
0
Tony