Alors que les accepted answer œuvres, et est correcte en ce qui concerne la question principale étant des caractères « larges », il y a quelques idées fausses et les aspects techniques de la question qui devraient être abordés afin d'avoir une meilleure compréhension de ce qui est vraiment se passe ici, à la fois dans .NET et dans SQL Server.
Première:
J'ai deux chaînes avec une valeur double octet et l'autre est un seul octet un.
Non, vous ne le faites pas. Vous avez deux chaînes Unicode, codées comme UTF-16 Little Endian (qui fonctionne comme Windows et .NET). Et en termes pratiques, la plupart du temps, les caractères sont codés sur deux octets, ce qui ne couvre que 62 000 à 63 000 caractères (soit les points de code entre U + 0000 et U + FFFF - ou 0 - 65 535 - sont des caractères "valides"). Mais Unicode permet de mapper un peu plus de 1,1 million de points de code, et actuellement il en compte un peu plus de 260 000 already mapped. Les points de code au-dessus de U + FFFF/65,535, connus sous le nom de caractères supplémentaires, sont mappés à des ensembles de deux valeurs à deux octets connus sous le nom de paires de substitution. Ainsi, alors qu'ils sont moins fréquemment utilisés, la majorité des points de code Unicode sont en réalité de 4 octets.
Deuxième:
Le résultat de la comparaison de chaînes de caractères faux, comment puis-je les amener à comparer correctement
Les lettres s1 = "smatsumoto11"
sont appelés caractères « » pleine chasse. Vous pouvez voir la liste complète d'entre eux ici:
http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:East_Asian_Width=Fullwidth:]
Quelques explications pour lesquelles il existe différentes largeurs, en premier lieu se trouvent ici:
http://unicode-table.com/en/blocks/halfwidth-and-fullwidth-forms/
Si vous voulez comparez les deux chaînes de la Question pour qu'elles soient égales, vous pouvez soit utiliser la méthode String.Compare(String, String, CultureInfo, CompareOptions) comme mentionné dans la réponse @ Arnout, soit utiliser CompareInfo.Compare(String, String, CompareOptions) comme suit:
CompareInfo.Compare(s1, s2, CompareOptions.IgnoreWidth)
Troisième:
Dans le même scénario, si vous avez une colonne nvarchar dans le serveur SQL qui contient la valeur smatsumoto11, une requête pour récupérer les données avec la condition where ayant la chaîne smatsumoto11 retournera la même rangée.
Ceci est une manière potentiellement dangereuse de penser à des comparaisons de chaînes. Il n'y a pas de façon particulière que les chaînes se comparent dans pratiquement n'importe quelle base de données, sauf si les chaînes sont en ASCII 7 bits (valeurs 0 - 127) qui n'incluent même pas les Pages de Code, et je ne sais pas . Les comparaisons sont basées sur le LCID/Locale/Culture/Collation particulier. Le classement par défaut dans SQL Server (au moins aux États-Unis) est SQL_Latin1_General_CP1_CI_AS
, qui est sensible à la casse et sensible aux accents. Il utilise également la page de code 1252 (qui affecte les données CHAR/VARCHAR, pas NCHAR/NVARCHAR) et la culture «en-US». Les classements pour d'autres cultures/LCID peuvent ne pas égaler Fullwidth et "half-width". Et, les classements qui ont _WS
dans leur nom ne correspondraient certainement pas à ces deux chaînes car _WS
signifie «Largeur sensible», qui est la valeur par défaut pour les comparaisons .NET si vous ne spécifiez pas l'option CompareOptions.IgnoreWidth
.
Si vous exécutez la requête suivante pour trouver les classements qui ont _WS
en leur nom, vous constaterez qu'il ya 1776 sur 3885 Les classements totaux qui correspondent qui sont Width sensibles et serait pas match de ces deux chaînes (à moins dans SQL Server 2012). Bien sûr, il y a également 262 classements binaires (c'est-à-dire les noms se terminant soit par le _BIN
obsolète ou le _BIN2
préféré) qui n'égaleraient pas non plus ces chaînes, mais ce n'est pas un problème de sensibilité de largeur.
SELECT *
FROM sys.fn_helpcollations()
WHERE [name] LIKE N'%[_]WS%'
ORDER BY [name];
-- 1776 out of 3885 on SQL Server 2012
En outre, comme je viens de mentionner, le malheureux (et dépréciée) par défaut Collation de SQL_Latin1_General_CP1_CI_AS
, ou même la meilleure version de Latin1_General_100_CI_AS
, est insensible à la casse. Donc les chaînes que vous comparez sont toutes minuscules donc elles sont égales quand vous utilisez juste CompareOptions.IgnoreWidth
, mais si vous voulez émuler ces classements particuliers dans SQL Server, alors le comportement par défaut de .NET pour être sensible à la casse ne correspondrait pas au SQL Comportement du serveur Afin de mieux correspondre au comportement SQL Server (au moins pour les classements, ou tout marqué comme ayant _CI
et pas ayant _WS
, vous devez inclure également l'option CompareOptions.IgnoreCase
comme suit:
CompareInfo.Compare(s1, s2, CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase)
// or
String.Compare(s1, s2, CultureInfo.CurrentCulture,
CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase)
Ressources supplémentaires:
Comparing Strings in the .NET Framework
Best Practices for Using Strings in the .NET Framework
"J'ai essayé quelques options mentionnées sur MSDN mais elles ne semblent pas fonctionner." Vous devez nous dire ce que vous avez essayé. –
En outre, d'où obtenez-vous la chaîne à un octet? –
En outre, si la chaîne à un octet est stockée dans un objet C# 'string', elle est déjà sous forme 2 octets. Peut-être que les chaînes proviennent de pages de code différentes, ou de codages différents, et ne se comparent donc pas comme prévu. –