代码之家  ›  专栏  ›  技术社区  ›  salvationishere

无法将“System.Object[]”类型的对象强制转换为“System.String[]”类型

  •  3
  • salvationishere  · 技术社区  · 14 年前

    我正在开发一个C vs 2008/SQL Server网站应用程序。我是ASP.NET的新手。但是,我在下面代码的最后一行得到了上面的错误。你能给我建议怎么修这个吗?这编译正确,但在运行之后遇到了这个错误。

    我所要做的就是将“dt”第二行中的项存储到字符串参数中。第一行是标题,所以我不需要这些值。第二行是第一行值。我的SQL存储过程需要这些值作为字符串。所以我要解析第二行数据并将其加载到2个字符串参数中。我在下面添加了更多代码。

    DataTable dt; 
    Hashtable ht;
    string[] SingleRow;
    ...
    SqlConnection conn2 = new SqlConnection(connString);
    SqlCommand cmd = conn2.CreateCommand();
    cmd.CommandText = "dbo.AppendDataCT";
    cmd.Connection = conn2;
    SingleRow = (string[])dt.Rows[1].ItemArray;
                SqlParameter sqlParam = cmd.Parameters.AddWithValue("@" + ht[0], SingleRow[0]);
                sqlParam.SqlDbType = SqlDbType.VarChar;
                SqlParameter sqlParam2 = cmd.Parameters.AddWithValue("@" + ht[1], SingleRow[1]);
                sqlParam2.SqlDbType = SqlDbType.DateTime;
    

    我的错误:

    System.InvalidCastException was caught
      Message="Unable to cast object of type 'System.Object[]' to type 'System.String[]'."
      Source="App_Code.g68pyuml"
      StackTrace:
           at ADONET_namespace.ADONET_methods.AppendDataCT(DataTable dt, Hashtable ht) in c:\Documents and Settings\Admin\My Documents\Visual Studio 2008\WebSites\Jerry\App_Code\ADONET methods.cs:line 88
      InnerException: 
    
    6 回复  |  直到 8 年前
        1
  •  1
  •   Michael Petrotta user3140870    14 年前

    嗯,你想访问数据表的属性 dt ,但您可能希望该表包含 AppendDataCT 查询。没有。也要注意行索引访问:C中的数组是基于0的,并且 dt.Rows[1] 将检索 第二 表中的行。

    除此之外,检查文档 DataRow.ItemArray . 该方法返回一个对象数组,而不是字符串数组。即使您的行只包含字符串,您仍然要处理一个对象数组,并且必须这样处理它。你可以把每个 个人 将行中的项转换为字符串,如果该列的数据类型正确:

    foreach (string s in dt.Rows[1].ItemArray)
    {
      //...
    }
    

    编辑 :好的,根据你的编辑,我知道你想做什么。有许多不同的方法可以做到这一点,我特别建议您远离哈希表,转向类似于 Dictionary -你会节省很多时间来制造悲伤。也就是说,下面是对代码的最简单修改:

    DataRow dr = dt.Rows[1]; // second row
    SqlParameter p1 = cmd.Parameters.AddWithValue((string)ht[0], (string)dr[0]);
    SqlParameter p2 = ...
    

    您不需要前导“@”,ADO.NET会为您添加它。只要在键0处有一个字符串(这是使用哈希表的一种相当非标准的方法,通常您会有某种描述性键),并且如果数据表中的第一列包含字符串,则(字符串)强制转换将起作用。

    我建议你看看 typed datasets generic collections . 这里缺少它们会使代码有些脆弱。

        2
  •  9
  •   Guffa    14 年前

    不能将对象数组强制转换为字符串数组,必须强制转换数组中的每个项,因为如果可以强制转换,则必须检查每个项。你可以使用 Cast 方法:

    SingleRow = dt.Rows[1].ItemArray.Cast<string>().ToArray();
    
        3
  •  3
  •   Marc Gravell    14 年前
    string[] arr = Array.ConvertAll(dt.Rows[1].ItemArray, o => (string)o);
    

    (您也可以使用 Cast<T>().ToArray() 但这种方法适用于更多的框架版本,从一开始就获得正确的数组大小,而不是调整它的大小)

        4
  •  1
  •   mamoo    14 年前

    每个列项都有它自己的类型,这可能与字符串不同,因此如果要将每个行值存储到一个数组中,则必须使用循环或LINQ(我没有测试过此代码段,但应该这样做):

    (from columnVal in dt.Rows[1].ItemArray
    select columnVal.ToString()).ToArray();
    
        5
  •  0
  •   Oliver Hanappi    14 年前

    您可以使用LINQ:

    var yourStringArray = dt.Rows[1].ItemArray
        .Select(o => (o ?? (object)String.Emtpy).ToString())
        .ToArray();
    

    这将使用ToString()将数组的每个项转换为字符串,如果该项为空,则返回空字符串。

        6
  •  0
  •   code4life    14 年前

    这个怎么样:做 string[] SingleRow 进入之内 object[] SingleRow 这会让线路

    SingleRow = (object[])dt.Rows[1].ItemArray;
    

    正确执行。随后,当您需要以字符串数组的形式访问其值时,请强制转换它或LINQ如下选择它:

    objectArray.Select<object, string>
       (c => (c != null ? c.ToString() : "")).ToArray();
    

    确保添加以下用法:

    using System.Linq;
    using System.Collections.Generic;