Linq to SQL comment faire “où dans (liste de valeurs)”

J’ai une fonction où j’obtiens une liste d’identifiants et je dois renvoyer la liste correspondant à une description associée à l’identifiant. Par exemple:

public class CodeData { ssortingng CodeId {get; set;} ssortingng Description {get; set;} } public List GetCodeDescriptionList(List codeIDs) //Given the list of institution codes, return a list of CodeData //having the given CodeIds } 

Donc, si je créais le sql pour cela moi-même, je ferais simplement quelque chose comme ceci (où la clause in contient toutes les valeurs de l’argument codeIds):

 Select CodeId, Description FROM CodeTable WHERE CodeId IN ('1a','2b','3') 

Dans Linq to Sql, je n’arrive pas à trouver l’équivalent de la clause “IN”. Le meilleur que j’ai trouvé jusqu’à présent (qui ne fonctionne pas) est:

  var foo = from codeData in channel.AsQueryable() where codeData.CodeId == "1" || codeData.CodeId == "2" select codeData; 

Le problème est que je ne peux pas générer dynamicment une liste de clauses “OR” pour linq en sql, car elles sont définies au moment de la compilation.

Comment accomplir une clause where qui vérifie une colonne est dans une liste dynamic de valeurs utilisant Linq to Sql?

Utilisation

 where list.Contains(item.Property) 

Ou dans votre cas:

 var foo = from codeData in channel.AsQueryable() where codeIDs.Contains(codeData.CodeId) select codeData; 

Mais vous pourriez aussi bien faire cela en notation par points:

 var foo = channel.AsQueryable() .Where(codeData => codeIDs.Contains(codeData.CodeId)); 

Vous pouvez également utiliser:

 List codes = new List(); codes.add(1); codes.add(2); var foo = from codeData in channel.AsQueryable() where codes.Any(code => codeData.CodeID.Equals(code)) select codeData; 

J’avais utilisé la méthode dans la réponse de Jon Skeet, mais une autre survenue avec Concat . La méthode Concat s’est légèrement améliorée dans un test limité, mais c’est un problème et je vais probablement m’en tenir aux Contains , ou peut-être que j’écrirai une méthode d’assistance pour le faire pour moi. De toute façon, voici une autre option si quelqu’un est intéressé:

La méthode

 // Given an array of id's var ids = new Guid[] { ... }; // and a DataContext var dc = new MyDataContext(); // start the queryable var query = ( from thing in dc.Things where thing.Id == ids[ 0 ] select thing ); // then, for each other id for( var i = 1; i < ids.Count(); i++ ) { // select that thing and concat to queryable query.Concat( from thing in dc.Things where thing.Id == ids[ i ] select thing ); } 

Test de performance

Ce n'était pas scientifique à distance. J'imagine que votre structure de firebase database et le nombre d'ID impliqués dans la liste auront un impact significatif.

J'ai mis en place un test où j'ai effectué 100 essais de Concat et Contains où chaque essai impliquait la sélection de 25 lignes spécifiées par une liste aléatoire de clés primaires. J'ai couru environ une douzaine de fois, et la plupart du temps, la méthode Concat est 5 à 10% plus rapide, bien qu'une fois la méthode Contains gagnée par un simple sminkgen.

  var filterTransNos = (from so in db.SalesOrderDetails where ItemDescription.Contains(ItemDescription) select new { so.TransNo }).AsEnumerable(); listreceipt = listreceipt.Where(p => filterTransNos.Any(p2 => p2.TransNo == p.TransNo)).ToList();