4

私はC#VS 2008 / SQLServerWebサイトアプリケーションを開発しています。私はASP.NETの初心者です。ただし、次のコードの最後の行で上記のエラーが発生します。これを修正する方法についてアドバイスをいただけますか?これは正しくコンパイルされますが、実行後にこのエラーが発生します。

私がやろうとしているのは、「dt」の2行目の項目を文字列パラメータに格納することだけです。最初の行はヘッダーなので、これらの値は必要ありません。2行目は、値の最初の行です。私のSQLストアドプロシージャでは、これらの値を文字列として必要とします。したがって、データの2行目を解析し、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: 
4

6 に答える 6

11

オブジェクトの配列を文字列の配列にキャストすることはできません。各アイテムをキャストできるかどうかを確認する必要があるため、配列内の各アイテムをキャストする必要があります。Castそのための方法を使用できます。

SingleRow = dt.Rows[1].ItemArray.Cast<string>().ToArray();
于 2010-06-06T21:56:39.970 に答える
3
string[] arr = Array.ConvertAll(dt.Rows[1].ItemArray, o => (string)o);

( を使用することもできますがCast<T>().ToArray()、このアプローチはより多くのフレームワーク バージョンで機能し、サイズを変更するのではなく、配列のサイズを最初から正しく取得します)

于 2010-06-06T22:08:36.617 に答える
2

うーん。DataTable のプロパティにアクセスしようとしていますが、そのテーブルにクエリdtの結果が含まれていることを期待しているようです。AppendDataCTそうではありません。行インデックス アクセスにも注意してください。C# の配列は 0 ベースであり、テーブルの2 番目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 に文字列がある限り機能します (これは、ハッシュテーブルを使用するためのかなり非標準的な方法です。通常、何らかの説明的なキーがあります)。データテーブルの最初の列に文字列。

型指定されたデータセットジェネリック コレクションを参照することをお勧めします。ここにそれらがないと、コードがやや脆弱になります。

于 2010-06-06T22:00:18.163 に答える
1

各列項目には独自の型があり、文字列とは異なる場合があるため、各行の値を配列に格納する場合は、ループまたは LINQ を使用して 1 つずつ実行する必要があります (テストしていません)。このスニペットですが、それは仕事をする必要があります):

(from columnVal in dt.Rows[1].ItemArray
select columnVal.ToString()).ToArray();
于 2010-06-06T22:00:43.123 に答える
0

そのためにLINQを使用できます:

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

これは、ToString() を使用して配列の各項目を文字列に変換し、項目が null の場合は空の文字列を返します。

于 2010-06-06T21:58:24.430 に答える
0

これはどうですか: make string[] SingleRowinto 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;
于 2010-06-06T22:42:31.163 に答える