2011-09-17
■[ASP.NET][トラブルシュート]ObjectDataSourceにはDataTableを双方向でデータバインドできない
ObjectDataSourceにはDataTableを双方向でデータバインドできません。
どういうこと?
以下のサンプルで説明します。
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication3._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DataObjectTypeName="WebApplication3.HogeDataSet+hogeDataTable" DeleteMethod="Update" InsertMethod="Update" SelectMethod="GetData" TypeName="WebApplication3.DataAccesser" UpdateMethod="Update"></asp:ObjectDataSource> </div> <asp:DetailsView ID="DetailsView1" runat="server" AllowPaging="True" AutoGenerateRows="False" DataSourceID="ObjectDataSource1" Height="50px" Width="125px"> <Fields> <asp:BoundField DataField="col1" HeaderText="col1" SortExpression="col1" /> <asp:BoundField DataField="col2" HeaderText="col2" SortExpression="col2" /> <asp:CommandField ShowInsertButton="True" /> </Fields> </asp:DetailsView> </form> </body> </html>
Default.aspx.cs
using WebApplication3.HogeDataSetTableAdapters; namespace WebApplication3 { public partial class _Default : System.Web.UI.Page { } public class DataAccesser { public HogeDataSet.hogeDataTable GetData() { // HogeDataSetは型指定されたDataSetです。 HogeDataSet.hogeDataTable t = new HogeDataSet.hogeDataTable(); using(hogeTableAdapter a = new hogeTableAdapter()) { a.Fill(t); } return t; } public void Update(HogeDataSet.hogeDataTable dataTable) { using(hogeTableAdapter a = new hogeTableAdapter()) { a.Update(dataTable); } } } }
データ表示
データ表示は問題なくできます。
データ登録
しかし、データ登録をすると以下の例外が発生します。
"ObjectDataSource 'ObjectDataSource1' の DataObjectTypeName プロパティによって指定された型上の 'col1' というプロパティが見つかりませんでした。"
どうして?
DataTableに 'col1' というプロパティがないからです。
どうすれば?
Update、Delete、Insertを実装する場合は、面倒でもデータクラスを作成します。
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication3._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DataObjectTypeName="WebApplication3.Hoge" DeleteMethod="UpdateList" InsertMethod="UpdateList" SelectMethod="GetList" TypeName="WebApplication3.DataAccesser" UpdateMethod="UpdateList"></asp:ObjectDataSource> </div> <asp:DetailsView ID="DetailsView1" runat="server" AllowPaging="True" AutoGenerateRows="False" DataSourceID="ObjectDataSource1" Height="50px" Width="125px"> <Fields> <asp:BoundField DataField="col1" HeaderText="col1" SortExpression="col1" /> <asp:BoundField DataField="col2" HeaderText="col2" SortExpression="col2" /> <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" ShowInsertButton="True" /> </Fields> </asp:DetailsView> </form> </body> </html>
Default.aspx.cs
using System.Collections.Generic; using System.Web.UI.MobileControls; namespace WebApplication3 { public partial class _Default : System.Web.UI.Page { } public class DataAccesser { public List<Hoge> GetList() { List<Hoge> hogeList = new List<Hoge>() { new Hoge() { col1 = 0, col2 = 1 }, new Hoge() { col1 = 10, col2 = 11 }, }; return hogeList; } public void UpdateList(Hoge hoge) { // 更新処理を実装する } } /// <summary> /// 必要なプロパティを実装したデータクラス。 /// </summary> public class Hoge { public int col1 { get; set; } public int col2 { get; set; } } }
これで更新できるようになります。
ちなみに
スコット・ガスリー氏のブログ(http://codezine.jp/article/detail/6164)では以下のように述べられています。
現在利用できる別のオプションは、ObjectDataSourceコントロールの使用です。このコントロールは、データアクセス層から、UIコードをよりクリーンに分別し、データコントロールがページングやソートなどの自動機能を提供できるようにします。しかし、データの選択では上手くいっても、双方向のデータバインディングを実施した時はまだ面倒で、簡単な(複雑な型の”深い”バインディングのない)プロパティだけしかサポートしなかったり、(エラー検証なども含む)多くのシナリオを処理するために、多くの複雑なコードを書かなければいけなかったりします。
以降2011/10/05追記
データクラスの代わりに型指定したDataRowが使えるのでは?
DataRowは引数のないPublicなコンストラクタがないので駄目です。
ObjectDataSource コントロールは、リフレクションを使用してビジネス オブジェクトのインスタンスを作成し、作成したインスタンスに対してメソッドを呼び出してデータを更新、挿入、および削除します。
- 1 http://k.hatena.ne.jp/keywordblog/Visual SourceSafe
- 1 http://s.luna.tv/search.aspx?q=Thunderbird メール タスクバー&s=1&channel=top&ptn=e31f722c-2b76-638a-92a5-709b0cb3a160
- 1 http://www.google.co.jp/hws/search?q="Mouse+Without+Borders"+社内LAN&client=fenrir-sub&channel=selection&safe=off&adsafe=off&hl=ja&lr=all&ie=UTF-8&oe=UTF-8&start=10&br=
- 1 http://www.google.co.jp/search?gcx=c&sourceid=chrome&ie=UTF-8&q=jquery+1.6.4
- 1 http://www.google.co.jp/search?q=Googl todo&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja:official&hl=ja&client=firefox-a
- 1 http://www.google.co.jp/search?q=microsoft+sourcesafe+vbproj タイムスタンプ&hl=ja&source=hp&gs_sm=e&gs_upl=1638l2792l0l5788l5l5l0l1l1l0l219l657l1.2.1l4l0&oq=microsoft+sourcesafe+vbproj ?%8
- 1 http://www.google.co.jp/url?sa=t&source=web&cd=1&ved=0CCYQFjAA&url=http://d.hatena.ne.jp/JHashimoto/20101103/1288743837&rct=j&q=outlook 2010 テンプレート&ei=9Zl6TvayFaHNmAXTxdSdAQ&usg=AFQjCNFDxEbR6
- 1 http://www.google.co.jp/url?sa=t&source=web&cd=1&ved=0CCkQFjAA&url=http://d.hatena.ne.jp/JHashimoto/20110722/1311302575&rct=j&q=Npgsql.NpgsqlFactory, Npgsql, Version=2.0.11.91&ctbs=lr:lang_1ja&ei=Epl6TvrWC-PemAXm4o2kAQ&usg=AFQjCNFe
- 1 http://www.google.co.jp/url?sa=t&source=web&cd=7&sqi=2&ved=0CFcQFjAG&url=http://d.hatena.ne.jp/JHashimoto/20110603/1307081327&rct=j&q=wpf datagrid パフォーマンス&ei=ZJZ6TvPdCM2emQW_68THAQ&us






