【问题标题】:very strange string unique issue in C#C#中非常奇怪的字符串唯一问题
【发布时间】:2009-08-11 15:18:23
【问题描述】:

我正在使用 VSTS2008 + C# + .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 无法正确显示我的字符串代码������,这是我在 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);
        }
    }

【问题讨论】:

  • 你试过测试buf[0]==buf[1]的值吗?我真的不知道字符串中的“�”是怎么回事。
  • 感谢 JoshJordan,来自 String.Compare,输出为 0,这意味着它们是相同的。从显示角度(人眼角度)来看,它们是不同的。这是 VSTS 2008 的屏幕快照,有什么想法吗? i28.tinypic.com/2j10ehg.jpg
  • 请参考我上面的图片,StackOverflow 无法正确显示。谢谢。
  • 好吧,George - 如果 String.Compare 返回 0,这些字符串被认为是相同的,并且尝试将它们都插入到强制唯一约束的列中不应该(也不会)起作用 - 通过设计!
  • 嗨,Marc,从显示的角度来看,它们是不同的。这就是为什么我如此困惑。有没有cmets?

标签: c# sql .net visual-studio-2008 ado.net


【解决方案1】:

我看到您在比较中使用了 InvariantCulture。您应该使用 Ordinal(逐个字符的文字比较)或 CurrentCulture(将替换到位 - 例如 Æ === AE)进行比较。

将字符输入为 Unicode 字符串可能会获得更好的运气,例如:

string text = "\uEFBF\uBDEF\uBFBD\uEFBF";
string text2= "\uEFBF\uBD0D\uAEFB\uFBDE\uFBFB";

我得到了一些中文/日文字符(未完全粘贴):

string text = "뷯뾽";
string text2 = "봍껻ﯞﯻ";

CurrentCulture 会知道一个符号可以代表 2 个其他符号,因此使用它会是一个不错的选择。 Ordinal 只会注意到长度不同。如果它们的长度相同,并且每个字符的每个 Unicode 值都相同,那么它将成功。

【讨论】:

    【解决方案2】:

    这看起来像字节顺序标记 (BOM) - http://en.wikipedia.org/wiki/Byte_order_mark

    在比较时,BOM 可能会被剥离,因此它们会是相同的吗?

    【讨论】:

      【解决方案3】:

      当其中 1 个字符串被转换为存储在数据表中时,它会产生与另一个字符串相同的字符串。 所以对 dataTable 的唯一约束使它抛出异常。

      【讨论】:

      • 为什么 DB 认为它们是相同的?从显示上看,它们明显不同。 :-)
      【解决方案4】:

      不确定这些很酷的字符使用什么字体或字符集,但它们的排序似乎不太好。 Compare() 基于字符串的可排序性工作,这就是为什么文化对于比较文化敏感字符串非常重要的原因。从排序的角度来看,这些字符串不会返回不同的结果,因此它们实际上是“相同的”。 String.Equals() 方法会将它们显示为不同的。

      buf[0].Equals(buf[1]) = false
      

      不知道为什么需要使用特殊字符,但如果这是一个“唯一”键的要求,那可能是个问题。我假设数据表使用类似的比较来验证唯一列值,因此将两行视为重复。

      【讨论】:

        【解决方案5】:

        也许关闭dataTable唯一强制约束,并实现自己的唯一检查方法?

        【讨论】:

          【解决方案6】:

          您的问题可能与您的角色是一个特殊的 unicode 字符有关。

          "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"
          

          http://en.wikipedia.org/wiki/Unicode_Specials

          【讨论】:

            猜你喜欢
            • 2021-08-26
            • 2011-07-26
            • 2018-07-16
            • 1970-01-01
            • 2013-02-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多