Невозможно привести объект типа "System.Object[]" к типу "System.String[]".
Я занимаюсь разработкой веб-приложения на 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 ответов
Хммм. Вы пытаетесь получить доступ к свойствам 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 добавит это для вас. Приведение (string) будет работать до тех пор, пока в ключе 0 есть строка (что является довольно нестандартным способом использования хеш-таблиц - у вас обычно будет какой-то описательный ключ), и если первый столбец в вашей таблице данных содержит строки.
Я рекомендую вам взглянуть на типизированные наборы данных и общие коллекции. Отсутствие их здесь делает ваш код несколько хрупким.
Вы не можете преобразовать массив объектов в массив строк, вы должны преобразовать каждый элемент в массиве, так как каждый элемент должен быть проверен, если он может быть приведен. Вы можете использовать Cast
метод для этого:
SingleRow = dt.Rows[1].ItemArray.Cast<string>().ToArray();
string[] arr = Array.ConvertAll(dt.Rows[1].ItemArray, o => (string)o);
(вы также можете использовать Cast<T>().ToArray()
, но этот подход работает на нескольких версиях фреймворка и с самого начала получает правильный размер массива, а не изменяет его размер)
Каждый элемент столбца имеет свой собственный тип, который может отличаться от String, поэтому, если вы хотите сохранить каждое значение строки в массиве, вы должны сделать это один за другим с циклом или с LINQ (я не проверял этот фрагмент, но должен делать свою работу):
(from columnVal in dt.Rows[1].ItemArray
select columnVal.ToString()).ToArray();
Вы можете использовать LINQ для этого:
var yourStringArray = dt.Rows[1].ItemArray
.Select(o => (o ?? (object)String.Emtpy).ToString())
.ToArray();
Это преобразует каждый элемент массива в строку с помощью ToString() и возвращает пустую строку, если элемент является нулевым.
Как насчет этого: сделать 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;