- PR -

複数列の主キーをもつデータソースへの更新

1
投稿者投稿内容
hiromo
会議室デビュー日: 2004/05/18
投稿数: 3
投稿日時: 2004-05-18 13:26
VB.NETでWebアプリケーションを開発しています。

複数列の主キーをもつデータソースへ DataSet の変更内容を更新したいと思います。

ソーステーブルの主キー制約情報は DataAdapter の FillSchema メソッドを
呼び出して DataSet に設定しています。
DataRowCollection の Find メソッドを呼び出して、データセットの
特定の行をみつけ、戻り値をDataRowオブジェクトに格納しているのですが、
「指定されたキャストは有効ではありません。」
というエラーが表示されます。

主キーが1つの時は正常にできたのですが、なにが原因なのか分かりません。
どなたかご存知でしたらご教授をよろしくお願いいたします。

=============================
<ソース>
1: Private Sub Button2_Click(ByVal sender As 〜) Handles Button2.Click
2: Dim strSQL As String = "SELECT id, day, val FROM " & tablename
3: Dim da As New SqlDataAdapter(strSQL, myConnection)
4: Dim builder As New SqlCommandBuilder(da)
5: Dim ds As New DataSet
6: Dim dr As DataRow
7: Dim findTheseVals(1) As Object
8:
9: da.FillSchema(ds, SchemaType.Mapped, tablename)
10: da.Fill(ds, tablename)
11:
12: findTheseVals(0) = 3 ' id(主キー)
13: findTheseVals(1) = "9999/12/31" ' day(主キー)
14:
15: dr = ds.Tables(tablename).Rows.Find(findTheseVals)
16: dr.Item("val") = 0
17: da.Update(ds, tablename)
18: ds.AcceptChanges()
19: End Sub
=============================
<エラー>
例外の詳細: System.InvalidCastException: 指定されたキャストは有効ではありません。

ソース エラー:
行 13: findTheseVals(1) = "9999/12/31" ' day(主キー)
行 14:
行 15: dr = ds.Tables(tablename).Rows.Find(findTheseVals)
行 16: dr.Item("val") = 0
行 17: da.Update(ds, tablename)

ソース ファイル : 行 15

スタック トレース:
[InvalidCastException: 指定されたキャストは有効ではありません。]
System.Data.Common.DateTimeStorage.CompareToValue(Int32 recordNo, Object value)
System.Data.DataColumn.CompareToValue(Int32 record1, Object value) +11
System.Data.Index.CompareRecordToKey(Int32 record1, Object[] vals) +130
System.Data.Index.FindRecordByKey(Object[] key, Boolean findFirst) +48
System.Data.Index.FindRecords(Object[] key) +67
System.Data.DataTable.FindRow(DataKey key, Object[] values)
System.Data.DataTable.FindByPrimaryKey(Object[] values)
System.Data.DataRowCollection.Find(Object[] keys)
WebApplication1.WebForm3.Button1_Click(Object sender, EventArgs e) in C:\\Inetpub\\wwwroot\\WebApplication1\\WebForm3.aspx.vb:72
System.Web.UI.WebControls.Button.OnClick(EventArgs e)
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
System.Web.UI.Page.ProcessRequestMain() +1258
NAL-6295
ぬし
会議室デビュー日: 2003/01/26
投稿数: 966
お住まい・勤務地: 東京
投稿日時: 2004-05-18 14:58
NAL-6295です。
複数あることが原因なのではなく、DateTime型の項目に該当する値の設定に問題があります。

引用:

<ソース>
11:
12: findTheseVals(0) = 3 ' id(主キー)
13: findTheseVals(1) = "9999/12/31" ' day(主キー)
14:
15: dr = ds.Tables(tablename).Rows.Find(findTheseVals)
19: End Sub
=============================




引用:

<ソース>
11:
12: findTheseVals(0) = 3 ' id(主キー)
13: findTheseVals(1) = new DateTime(9999,12,31) ' day(主キー)
14:
15: dr = ds.Tables(tablename).Rows.Find(findTheseVals)
19: End Sub
=============================



とすると、うまく動作するでしょう。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-05-18 17:21
エラーメッセージには、その例外(エラー)が発生した原因が書かれています。エラーメッセージを読み取る訓練が必要、ということですね。


例外の詳細:
 ここに、どういう例外か、書かれています。
 今回は「System.InvalidCastException」で、キャスト(型変換)ができない、
 というエラーであるとわかります。

ソース エラー:
 ここに、例外が発生したソース上の行と、その近辺が表示されます。
 近辺も含めて表示されるのは、原因が発生した行ではなく、その前の設定に
 ある場合が多いからです。

スタック トレース:
 これは、下から順に実行時に呼び出された順番が書いてあります。
 今回は、「リクエスト処理」→「ポストバックイベントの発生処理」
 →「ボタンのクリックイベント」→「イベントハンドラ」(ここの73行目)
 →「行検索」→「キーによる検索」→「レコードの比較」
 →「時間型の変換」で、発生してることがわかります。
 #メソッド名より「何をしているか」を判断して日本語化しています


 このように、スタックトレースと例外の詳細から、「型変換で失敗」していることがわかります。例外の原因が「型変換で失敗」であり、『主キーが1つの時は検索できた』ことから、「2つめの主キーの型変換が失敗しているらしい」と、当たりを付けます。「2つめの主キーが問題」というところはあたっていますが、例外情報の読みが足りなかったようです。
hiromo
会議室デビュー日: 2004/05/18
投稿数: 3
投稿日時: 2004-05-18 17:31
NAL-6295様 ご返答ありがとうございます。
ご指摘のとおり、DateTime型の項目に該当する値の設定を変えたら
うまく動作しました。
とても助かりました。どうもありがとうございました。
hiromo
会議室デビュー日: 2004/05/18
投稿数: 3
投稿日時: 2004-05-18 17:57
Jitta様 ご返答ありがとうございます。
エラーメッセージの読みが浅かったですね。
今後はスタックトレースのエラーメッセージにも注意して
読もうと思います。
丁寧に教えてくださいましてありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)