132 votes

comparaison sensible à la casse entre linq et entités

Ce n'est pas une comparaison sensible à la casse dans Linq avec des entités:

 Thingies.First(t => t.Name == "ThingamaBob");
 

Comment puis-je effectuer une comparaison sensible à la casse avec Linq avec des entités?

184voto

Morteza Manavi Points 20486

C'est parce que vous êtes à l'aide de LINQ to entities qui est en fin de compte la conversion de vos Expressions Lambda dans les instructions SQL. Cela signifie que la sensibilité de cas est à la merci de votre Serveur SQL server qui a par défaut SQL_Latin1_General_CP1_CI_AS Classement et qui n'est PAS sensible à la casse.

À L'Aide De ObjectQuery.ToTraceString pour voir le SQL généré requête qui a été effectivement soumis à SQL Server, révèle le mystère:

string sqlQuery = ((ObjectQuery)context.Thingies
        .Where(t => t.Name == "ThingamaBob")).ToTraceString();


Lorsque vous créez une LINQ to entities requête LINQ to entities exploite le LINQ analyseur de commencer le traitement de la requête et la convertit en une expression LINQ arbre. L'expression LINQ arbre est ensuite transmise à l'Objet des Services de l'API, qui convertit l'expression de l'arbre à une commande de l'arbre. Il est ensuite envoyé vers le fournisseur de magasin (par exemple, SqlClient), qui convertissent la commande de l'arbre dans la base de données native texte de la commande. La requête est exécutée sur le magasin de données, et les résultats sont Matérialisées dans des Objets de l'Entité par l' Objet des Services. Aucune logique a été mis en entre à prendre en cas de sensibilité en compte.Donc, peu importe ce cas vous mettez dans votre prédicat, il sera toujours traiter comme de la même façon par votre Serveur SQL server, sauf si vous modifiez votre Sql Server Rassemble pour cette colonne.

Côté serveur solution:
Donc, la meilleure solution serait de modifier le Classement de la Nom de la colonne dans des Bidules table de RASSEMBLER Latin1_General_CS_AS qui est le cas sensetive par l'exécution de cette sur votre Serveur Sql server:

ALTER TABLE Thingies
ALTER COLUMN Name VARCHAR(25)
COLLATE Latin1_General_CS_AS

Pour plus d'informations sur Sql Server Rassemble, prendre un regard sur SQL SERVER – Assembler – casse SQL de la Requête de Recherche

Côté Client de la solution:
La seule solution que vous pouvez appliquer sur le côté client est d'utiliser LINQ to Objects faire encore une autre comparaison qui ne semble pas être très élégant:

Thingies.Where(t => t.Name == "ThingamaBob")
        .AsEnumerable()
        .First(t => t.Name == "ThingamaBob");

-4voto

Rune Borgen Points 102

J'ai bien aimé la réponse de Morteza et préférerais normalement régler le problème du côté serveur. Pour le côté client, j'utilise normalement:

 Dim bLogin As Boolean = False

    Dim oUser As User = (From c In db.Users Where c.Username = UserName AndAlso c.Password = Password Select c).SingleOrDefault()
    If oUser IsNot Nothing Then
        If oUser.Password = Password Then
            bLogin = True
        End If
    End If
 

Fondamentalement, 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 j'estime qu'il est plus facile de lire quand il y a beaucoup de critères en jeu.

-5voto

bloparod Points 808

Pas sûr de EF4, mais EF5 supporte ceci:

 Thingies
    .First(t => t.Name.Equals(
        "ThingamaBob",
        System.StringComparison.InvariantCultureIgnoreCase)
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X