Я использую VSTS2008 + С# +.Net 3.0. Вот мой код и соответствующее исключение из ADO.Net. Вот мой ввод двух строк в двоичной и текстовой форме, есть идеи, что не так? Почему две разные строки будут рассматриваться ADO.Net как одинаковые?
Сообщение об исключении:
An unhandled exception of type 'System.Data.ConstraintException' occurred in System.Data.dll
Additional information: Column 'Name' is constrained to be unique. Value '������' is already present.
Входные строки в двоичном и текстовом виде:
StackOverflow не отображается правильно для моего кода для строк here, вот снимок экрана для того, как он фактически выглядит в моем редакторе VSTS 2008.
Мой код:
static void Main(string[] args)
{
string[] buf = new string[] { "����", "������" };
CompareInfo ci = System.Globalization.CultureInfo.InvariantCulture.CompareInfo;
ci.Compare(buf[0], buf[1], CompareOptions.IgnoreWidth);
Console.WriteLine (String.Compare(buf[0], buf[1], StringComparison.InvariantCultureIgnoreCase));
DataTable bulkInserTable = new DataTable("BulkRequestTable");
bulkInserTable.CaseSensitive = true;
DataColumn column = null;
DataRow row = null;
// add Keyword column to datatable
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Name";
column.ReadOnly = true;
column.Unique = true;
bulkInserTable.Columns.Add(column);
foreach (string item in buf)
{
row = bulkInserTable.NewRow();
row["Name"] = item;
bulkInserTable.Rows.Add(row);
}
}
Я видел, что вы использовали InvariantCulture для сравнения. Вы должны использовать Ordinal (сравнение букв по символу) или CurrentCulture (что делает замену на место - например, Æ === AE), чтобы выполнить ваши сравнения.
Вам может быть повезло, если ввести символы в виде символов Unicode, например:
string text = "\uEFBF\uBDEF\uBFBD\uEFBF";
string text2= "\uEFBF\uBD0D\uAEFB\uFBDE\uFBFB";
У меня это как некоторые китайские/японские символы (не полностью вставляемые):
string text = "뷯뾽";
string text2 = "봍껻ﯞﯻ";
CurrentCulture будет знать, что один символ может представлять 2 других символа, поэтому это был бы хороший выбор для использования. Ординал просто заметит, что длины разные. Если они имеют одинаковую длину, и каждое значение Юникода одинаково для каждого символа, то оно будет успешным.
Это выглядит как метки байтов (BOM) - http://en.wikipedia.org/wiki/Byte_order_mark
Спецификации, вероятно, удаляются при сравнении, следовательно, они будут одинаковыми?
Когда 1 из строк преобразуется для хранения в файле данных, в результате получается одна и та же строка, что и другая. поэтому уникальное ограничение на dataTable заставляет исключить его.
Не уверен, какой шрифт или символ установлены в этих классных персонажах, но они, похоже, не очень хорошо сортируются. Compare() работает на основе сортировки строк, поэтому культура очень важна для сравнения чувствительных к культуре строк. Эти символьные строки не возвращаются как отличные от перспективы сортировки, поэтому они действуют "одинаково". Метод String.Equals() покажет их как разные.
buf[0].Equals(buf[1]) = false
Не уверен, зачем нужно использовать специальные символы, но если это требование иметь как "уникальные" ключи, которые могут быть проблемой. Я предполагаю, что datatable использует аналогичное сравнение для проверки уникальных значений столбца и поэтому видит две строки как дубликаты.
Ваша проблема, вероятно, связана с тем, что ваш персонаж является особым символом юникода.
"The replacement character � (often a black diamond with a white question mark)
is a symbol found in the Unicode standard at codepoint U+FFFD in the Specials
table. It is used to indicate problems when a system such as a text parser was
not able to decode a stream of data to a correct symbol"
возможно отключить единственное ограничение принудительного применения dataTable и реализовать свой собственный уникальный метод проверки?