Ce n'est pas une comparaison sensible à la casse dans LINQ to Entities:
Thingies.First(t => t.Name == "ThingamaBob");
Comment puis-je réaliser une comparaison sensible à la casse avec LINQ to Entities?
c#
.net
entity-framework-4
linq-to-entities
Ronnie Overby
la source
la source
Réponses:
En effet, vous utilisez LINQ To Entities, qui convertit finalement vos expressions Lambda en instructions SQL. Cela signifie que le respect de la casse est à la merci de votre serveur SQL qui par défaut a SQL_Latin1_General_CP1_CI_AS et qui n'est PAS sensible à la casse.
L'utilisation d' ObjectQuery.ToTraceString pour voir la requête SQL générée qui a été réellement soumise à SQL Server révèle le mystère:
Lorsque vous créez une requête LINQ to Entities , LINQ to Entities exploite l'analyseur LINQ pour commencer le traitement de la requête et la convertit en une arborescence d'expression LINQ. L'arborescence d'expression LINQ est ensuite transmise à l' API Object Services , qui convertit l'arborescence d'expression en une arborescence de commandes. Il est ensuite envoyé au fournisseur du magasin (par exemple SqlClient), qui convertit l'arborescence de commandes en texte de commande de la base de données native. La requête est exécutée sur le magasin de données et les résultats sont matérialisés en objets d'entité par Object Services. Aucune logique n'a été mise entre les deux pour tenir compte du respect de la casse. Ainsi, quel que soit le cas que vous mettez dans votre prédicat, il sera toujours traité de la même manière par votre serveur SQL, sauf si vous modifiez vos assemblages SQL Server pour cette colonne.
Solution côté serveur:
Par conséquent, la meilleure solution serait de modifier le classement de la colonne Nom dans la table Thingies en COLLATE Latin1_General_CS_AS, ce qui est sensible à la casse en exécutant ceci sur votre serveur SQL:
Pour plus d'informations sur les assemblages SQL Server , jetez un œil à la recherche de requêtes SQL sensible à la casse de l' assemblage SQL SERVER
Solution côté client:
La seule solution que vous pouvez appliquer côté client est d'utiliser LINQ to Objects pour faire encore une autre comparaison qui ne semble pas très élégante:
la source
Vous pouvez ajouter l'annotation [CaseSensitive] pour EF6 + Code-first
Ajouter ces classes
Modifiez votre DbContext, ajoutez
Alors fais
Add-Migration CaseSensitive
Update-Database
basé sur l'article https://milinaudara.wordpress.com/2015/02/04/case-sensitive-search-using-entity-framework-with-custom-annotation/ avec une correction de bogue
la source
WHERE
les conditions dans SQL Server sont insensibles à la casse par défaut. Faites-le sensible à la casse en remplaçant les classements par défaut de la colonne (SQL_Latin1_General_CP1_CI_AS
) parSQL_Latin1_General_CP1_CS_AS
.La manière fragile de faire ceci est avec le code. Ajoutez un nouveau fichier de migration, puis ajoutez-le dans la
Up
méthode:Mais
Vous pouvez créer une annotation personnalisée appelée "CaseSensitive" à l'aide des nouvelles fonctionnalités EF6 et vous pouvez décorer vos propriétés comme ceci:
Cet article de blog explique comment faire cela.
la source
La réponse donnée par @Morteza Manavi résout le problème. Pourtant, pour une solution côté client , une manière élégante serait la suivante (ajouter une double vérification).
la source
J'ai aimé la réponse de Morteza et je préférerais normalement la corriger côté serveur. Pour le côté client, j'utilise normalement:
En gros, vérifiez d'abord s'il y a un utilisateur avec les critères requis, puis vérifiez si le mot de passe est le même. Un peu long, mais je pense que c'est plus facile à lire quand il peut y avoir tout un tas de critères impliqués.
la source
Aucun des deux n'a
StringComparison.IgnoreCase
fonctionné pour moi. Mais cela a fait:la source
How can I achieve case sensitive comparison
Utilisez une chaîne.
De plus, vous n'avez pas à vous soucier de null et ne récupérez que les informations que vous souhaitez.
Utilisez StringComparision.CurrentCultureIgnoreCase pour ne pas respecter la casse.
la source
Je ne suis pas sûr de EF4, mais EF5 prend en charge ceci:
la source
StringComparison
enums fasse une différence. J'ai vu suffisamment de gens suggérer que ce genre de chose devrait fonctionner pour penser que le problème se trouve quelque part dans le fichier EDMX (db-first), bien que stackoverflow.com/questions/841226