J'ai lu qu'il n'était pas judicieux d'utiliser ToUpper et ToLower pour effectuer des comparaisons de chaînes insensibles à la casse, mais je ne vois aucune alternative en ce qui concerne LINQ-to-SQL. Les arguments ignoreCase et CompareOptions de String.Compare sont ignorés par LINQ-to-SQL (si vous utilisez une base de données sensible à la casse, vous obtenez une comparaison sensible à la casse même si vous demandez une comparaison insensible à la casse). ToLower ou ToUpper est-il la meilleure option ici? Est-ce que l'un est meilleur que l'autre? Je pensais avoir lu quelque part que ToUpper était meilleur, mais je ne sais pas si cela s'applique ici. (Je fais beaucoup de révisions de code et tout le monde utilise ToLower.)
Dim s = From row In context.Table Where String.Compare(row.Name, "test", StringComparison.InvariantCultureIgnoreCase) = 0
Cela se traduit par une requête SQL qui compare simplement row.Name avec "test" et ne renverra pas "Test" et "TEST" sur une base de données sensible à la casse.
LINQQuery.Contains("VaLuE", StringComparer.CurrentCultureIgnoreCase)
etLINQQuery.Except(new string[]{"A VaLUE","AnOTher VaLUE"}, StringComparer.CurrentCultureIgnoreCase)
. Wahoo!Réponses:
Comme vous le dites, il existe des différences importantes entre ToUpper et ToLower, et une seule est fiable lorsque vous essayez de faire des vérifications d'égalité insensibles à la casse.
Idéalement, la meilleure façon de faire une vérification d'égalité insensible à la casse serait :
NOTEZ CEPENDANT que cela ne fonctionne pas dans ce cas! Par conséquent, nous sommes coincés avec
ToUpper
ouToLower
.Notez l' ordinal IgnoreCase pour le rendre sûr. Mais exactement le type de vérification sensible à la casse que vous utilisez dépend de vos objectifs. Mais en général, utilisez Equals pour les vérifications d'égalité et Compare lorsque vous triez, puis choisissez le StringComparison approprié pour le travail.
Michael Kaplan (une autorité reconnue sur la culture et la gestion des personnages comme celle-ci) a publié des articles pertinents sur ToUpper vs ToLower:
Il dit "String.ToUpper - Utilisez ToUpper plutôt que ToLower, et spécifiez InvariantCulture afin de récupérer les règles de casse du système d'exploitation "
la source
J'ai utilisé
System.Data.Linq.SqlClient.SqlMethods.Like(row.Name, "test")
dans ma requête.Cela effectue une comparaison insensible à la casse.
la source
SqlClient
.J'ai essayé cela en utilisant l'expression Lambda, et cela a fonctionné.
List<MyList>.Any (x => (String.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)) && (x.Type == qbType) );
la source
List<>
, ce qui signifie que la comparaison a lieu en mémoire (code C #) plutôt qu'unIQueryable
(ouObjectQuery
) qui effectuerait la comparaison dans la base de données .Si vous passez une chaîne insensible à la casse dans LINQ-to-SQL, elle sera transmise au SQL sans modification et la comparaison se produira dans la base de données. Si vous souhaitez effectuer des comparaisons de chaînes insensibles à la casse dans la base de données, tout ce que vous avez à faire est de créer une expression lambda qui effectue la comparaison et le fournisseur LINQ-to-SQL traduira cette expression en une requête SQL avec votre chaîne intacte.
Par exemple cette requête LINQ:
est traduit en SQL suivant par le fournisseur LINQ-to-SQL:
Comme vous pouvez le voir, le paramètre de chaîne sera comparé en SQL, ce qui signifie que les choses devraient fonctionner exactement comme vous vous y attendez.
la source
Pour effectuer des requêtes Linq à Sql sensibles à la casse, déclarez que les champs «chaîne» sont sensibles à la casse en spécifiant le type de données du serveur à l'aide de l'un des éléments suivants;
ou
Remarque: Le «CS» dans les types de classement ci-dessus signifie «Sensible à la casse».
Cela peut être entré dans le champ «Type de données du serveur» lors de l'affichage d'une propriété à l'aide de Visual Studio DBML Designer.
Pour plus de détails, voir http://yourdotnetdesignteam.blogspot.com/2010/06/case-sensitive-linq-to-sql-queries.html
la source
la source
L'approche en 2 étapes suivante fonctionne pour moi (VS2010, ASP.NET MVC3, SQL Server 2008, Linq to SQL):
la source
!= -1
parce queIndexOf
"renvoie -1 si le caractère ou la chaîne n'est pas trouvé"Parfois, la valeur stockée dans la base de données peut contenir des espaces, l'exécution de cette opération peut donc échouer
La solution à ce problème est de supprimer de l'espace puis de convertir son boîtier puis de sélectionner comme ceci
Notez dans ce cas
customname correspond à la valeur de la base de données
UsersTBs est classe
title est la colonne Database
la source
N'oubliez pas qu'il y a une différence entre si la requête fonctionne et si elle fonctionne efficacement ! Une instruction LINQ est convertie en T-SQL lorsque la cible de l'instruction est SQL Server, vous devez donc penser au T-SQL qui serait produit.
L'utilisation de String.Equals ramènera très probablement (je suppose) toutes les lignes de SQL Server, puis effectuera la comparaison dans .NET, car il s'agit d'une expression .NET qui ne peut pas être traduite en T-SQL.
En d'autres termes, l'utilisation d'une expression augmentera votre accès aux données et supprimera votre capacité à utiliser des index. Cela fonctionnera sur de petites tables et vous ne remarquerez pas la différence. Sur une grande table, cela pourrait très mal fonctionner.
C'est l'un des problèmes qui existe avec LINQ; les gens ne pensent plus à la manière dont les déclarations qu'ils écrivent seront remplies.
Dans ce cas, il n'y a pas moyen de faire ce que vous voulez sans utiliser une expression - même pas en T-SQL. Par conséquent, vous ne pourrez peut-être pas le faire plus efficacement. Même la réponse T-SQL donnée ci-dessus (en utilisant des variables avec classement) entraînera très probablement l'ignorance des index, mais s'il s'agit d'une grande table, il vaut la peine d'exécuter l'instruction et de regarder le plan d'exécution pour voir si un index a été utilisé. .
la source