Я не ожидаю, что обработка текста как UCS-2 вызовет много проблем.
Преобразования регистра не должны быть проблемой, потому что (AFAIK) нет никаких отображений регистра выше BMP (кромеконечно же, отображение личности!), и, очевидно, суррогатные персонажи будут сопоставляться с самим собой.
Отбеливание каждого другого персонажа просто вызывает проблемы.На самом деле такие трансформации без учета ценностей персонажей - это всегда опасное занятие.Я вижу, что это происходит законно с усечением строки.Но если в результате появятся какие-то непревзойденные суррогаты, это само по себе не является огромной проблемой.Любая система, которая получает такие данные и заботится о них, вероятно, просто заменит непревзойденный суррогат заменяющим символом, если она вообще не хочет ничего с этим делать.
Очевидно, длина строки будет в байтах / 2а не количество символов, но количество символов не очень полезно в любом случае, как только вы начнете изучать глубину кодовых диаграмм Юникода.Например, вы не получите хороших результатов в моноширинном отображении после выхода из диапазона ASCII из-за сочетания символов, языков RTL, символов управления направлением, тегов и нескольких видов пробелов.Высокие значения кода будут наименьшей из ваших проблем.
Просто чтобы быть в безопасности, вы, вероятно, должны хранить свои клинописные тексты в другом столбце, чем имена археолога.: D
ОБНОВЛЕНИЕ теперь с эмпирическими данными!
Я только что выполнил тест, чтобы увидеть, что происходит с преобразованиями регистра.Я создал строку с английским словом TEST в верхнем регистре дважды - сначала на латинице, затем на десерте.Я применил преобразование в нижнем регистре к этой строке в .NET и в SQL Server.
. В версии .NET правильно прописаны все буквы в обоих сценариях.Версия SQL Server содержит только латинские символы в нижнем регистре и оставляет символы Deseret без изменений.Это соответствует ожиданиям относительно обработки UTF-16 стихов UCS-2.
using System;
using System.Data.SqlClient;
class Program
{
static void Main(string[] args)
{
string myDeseretText = "TEST\U00010413\U00010407\U0001041D\U00010413";
string dotNetLower = myDeseretText.ToLower();
string dbLower = LowercaseInDb(myDeseretText);
Console.WriteLine(" Original: {0}", DisplayUtf16CodeUnits(myDeseretText));
Console.WriteLine(".NET Lower: {0}", DisplayUtf16CodeUnits(dotNetLower));
Console.WriteLine(" DB Lower: {0}", DisplayUtf16CodeUnits(dbLower));
Console.ReadLine();
}
private static string LowercaseInDb(string value)
{
SqlConnectionStringBuilder connection = new SqlConnectionStringBuilder();
connection.DataSource = "(local)";
connection.IntegratedSecurity = true;
using (SqlConnection conn = new SqlConnection(connection.ToString()))
{
conn.Open();
string commandText = "SELECT LOWER(@myString) as LoweredString";
using (SqlCommand comm = new SqlCommand(commandText, conn))
{
comm.CommandType = System.Data.CommandType.Text;
comm.Parameters.Add("@myString", System.Data.SqlDbType.NVarChar, 100);
comm.Parameters["@myString"].Value = value;
using (SqlDataReader reader = comm.ExecuteReader())
{
reader.Read();
return (string)reader["LoweredString"];
}
}
}
}
private static string DisplayUtf16CodeUnits(string value)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (char c in value)
sb.AppendFormat("{0:X4} ", (int)c);
return sb.ToString();
}
}
Вывод:
Original: 0054 0045 0053 0054 D801 DC13 D801 DC07 D801 DC1D D801 DC13
.NET Lower: 0074 0065 0073 0074 D801 DC3B D801 DC2F D801 DC45 D801 DC3B
DB Lower: 0074 0065 0073 0074 D801 DC13 D801 DC07 D801 DC1D D801 DC13
На всякий случай, если у кого-либо установлен шрифт Deseret, вот фактическиеСтруны для вашего удовольствия:
Original: TEST????
.NET Lower: test????
DB Lower: test????