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