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

时间:2010-06-06 21:50:56

标签: c# visual-studio-2008 sql-server-2005-express

我正在开发一个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 个答案:

答案 0 :(得分:9)

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

SingleRow = dt.Rows[1].ItemArray.Cast<string>().ToArray();

答案 1 :(得分:3)

string[] arr = Array.ConvertAll(dt.Rows[1].ItemArray, o => (string)o);

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

答案 2 :(得分:1)

嗯。您正在尝试访问DataTable dt的属性,但看起来您可能希望该表包含AppendDataCT查询的结果。它没有。您也要小心行索引访问:C#中的数组是从0开始的,dt.Rows[1]将检索表中的第二行。

除此之外,请查看DataRow.ItemArray的文档。该方法返回一个对象数组,而不是一个字符串数组。即使你的行只包含字符串,你仍然在处理一系列对象,你将不得不这样对待它。您可以将行中的每个单个项目转换为字符串,如果这是该列的正确数据类型:

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

编辑:好的,为了回应您的编辑,我看到您正在尝试做什么。有很多不同的方法可以做到这一点,我特别建议你从HashTables转移到像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 datasetsgeneric collections。这里缺少它们会使您的代码变得有些脆弱。

答案 3 :(得分:1)

每个列项都有自己的类型,可以与String不同,所以如果你想将每个行值存储到一个数组中,你必须逐个循环,或者使用LINQ(我的避风港)没有测试过这个片段,但是应该这样做了):

(from columnVal in dt.Rows[1].ItemArray
select columnVal.ToString()).ToArray();

答案 4 :(得分:0)

您可以使用LINQ:

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

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

答案 5 :(得分:0)

如何:将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;