Dans T-SQL, vous pouvez avoir une requête comme:
SELECT * FROM Users WHERE User_Rights IN ("Admin", "User", "Limited")
Comment répliqueriez-vous cela dans une requête LINQ to Entities? Est-ce même possible?
la source
Dans T-SQL, vous pouvez avoir une requête comme:
SELECT * FROM Users WHERE User_Rights IN ("Admin", "User", "Limited")
Comment répliqueriez-vous cela dans une requête LINQ to Entities? Est-ce même possible?
Vous devez le mettre sur la tête en termes de la façon dont vous y pensez. Au lieu de faire "in" pour trouver les droits d'utilisateur de l'élément actuel dans un ensemble prédéfini de droits d'utilisateur applicables, vous demandez un ensemble prédéfini de droits d'utilisateur s'il contient la valeur applicable de l'élément actuel. C'est exactement de la même manière que vous trouveriez un élément dans une liste régulière dans .NET.
Il existe deux façons de procéder à l'aide de LINQ, l'une utilise la syntaxe de requête et l'autre utilise la syntaxe de méthode. Essentiellement, ils sont identiques et pourraient être utilisés de manière interchangeable selon votre préférence:
Syntaxe de requête:
var selected = from u in users
where new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights)
select u
foreach(user u in selected)
{
//Do your stuff on each selected user;
}
Syntaxe de la méthode:
var selected = users.Where(u => new[] { "Admin", "User", "Limited" }.Contains(u.User_Rights));
foreach(user u in selected)
{
//Do stuff on each selected user;
}
Ma préférence personnelle dans cette instance pourrait être la syntaxe de la méthode car au lieu d'affecter la variable, je pourrais faire le foreach sur un appel anonyme comme celui-ci:
foreach(User u in users.Where(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
//Do stuff on each selected user;
}
Syntaxiquement, cela semble plus complexe, et vous devez comprendre le concept d'expressions lambda ou de délégués pour vraiment comprendre ce qui se passe, mais comme vous pouvez le voir, cela condense assez le code.
Tout dépend de votre style de codage et de vos préférences - les trois exemples font la même chose légèrement différemment.
Une autre méthode n'utilise même pas LINQ, vous pouvez utiliser la même syntaxe de méthode en remplaçant «où» par «FindAll» et obtenir le même résultat, qui fonctionnera également dans .NET 2.0:
foreach(User u in users.FindAll(u => new [] { "Admin", "User", "Limited" }.Contains(u.User_Rights)))
{
//Do stuff on each selected user;
}
Cela devrait suffire à votre objectif. Il compare deux collections et vérifie si une collection a les valeurs correspondant à celles de l'autre collection
la source
Si vous utilisez VS2008 / .net 3.5, consultez l'astuce # 8 d'Alex James: http://blogs.msdn.com/alexj/archive/2009/03/26/tip-8-writing-where-in-style -queries-using-linq-to-entity.aspx
Sinon, utilisez simplement la méthode array.Contains (someEntity.Member).
la source
Je vais opter pour Inner Join dans ce contexte. Si j'aurais utilisé Contient, il répéterait 6 fois malgré le fait qu'il n'y ait qu'une seule correspondance.
Inconvénients de Contient
Supposons que j'ai deux objets de liste.
En utilisant Contains, il recherchera chaque élément de la liste 1 dans la liste 2, ce qui signifie que l'itération se produira 49 fois !!!
la source
Cela pourrait être la manière possible d'utiliser directement les méthodes d'extension LINQ pour vérifier la clause in
la source
J'ai également essayé de travailler avec une chose semblable à SQL-IN - interroger un modèle de données d'entité . Mon approche est un constructeur de chaînes pour composer une grosse expression OR. C'est terriblement moche, mais je crains que ce soit la seule façon de procéder en ce moment.
Eh bien, cela ressemble à ceci:
Utilisation des GUID dans ce contexte : Comme vous pouvez le voir ci-dessus, il y a toujours le mot "GUID" avant le GUID ifself dans les fragments de chaîne de requête. Si vous n'ajoutez pas cela,
ObjectQuery<T>.Where
lève l'exception suivante:J'ai trouvé cela dans les forums MSDN.
Matthias
... dans l'attente de la prochaine version de .NET et Entity Framework, quand tout ira mieux. :)
la source
Une méthode alternative à la réponse BenAlabaster
Tout d'abord, vous pouvez réécrire la requête comme ceci:
Certes, c'est plus «verbeux» et pénible à écrire mais ça marche tout de même.
Donc, si nous avions une méthode utilitaire qui facilitait la création de ce type d'expressions LINQ, nous serions en affaires.
avec une méthode utilitaire en place, vous pouvez écrire quelque chose comme ceci:
Cela crée une expression qui a le même effet que:
Mais ce qui, plus important, fonctionne réellement contre .NET 3.5 SP1.
Voici la fonction de plomberie qui rend cela possible:
Je ne vais pas essayer d'expliquer cette méthode, sinon de dire qu'elle construit essentiellement une expression de prédicat pour toutes les valeurs en utilisant valueSelector (c'est-à-dire p => p.User_Rights) et OU ces prédicats ensemble pour créer une expression pour l'ensemble prédicat
Source: http://blogs.msdn.com/b/alexj/archive/2009/03/26/tip-8-writing-where-in-style-queries-using-linq-to-entities.aspx
la source
Exemple réel:
la source
Sérieusement? Vous n'avez jamais utilisé
la source
Checks = NumValues * NumRows
. Comme il s'agit d'un calcul de type M * N, si l'un ou l'autre est petit, le temps pour effectuer chaque vérification requise sera également petit. J'ai ajouté la contrainte pour que cjm30305 sache comment configurer un environnement de test où montrer pourquoi sa solution est mauvaise.where new[] { 1, 2, 3 }.Contains(x)
fait moins de comparaisons alorswhere (x == 1 || x == 2 || x == 3)
?