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); } } } }
どうして?
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; } } }
これで更新できるようになります。
ちなみに
スコット・ガスリー氏のブログでは以下のように述べられています。
Webフォームモデルバインディング パート1:データの選択 (ASP.NET vNextシリーズ) (1/2):CodeZine
本稿は、Scott Guthrie氏のブログを、氏の許可を得て、翻訳、転載したものです。米Microsoft社の副社長で、ASP.NETやSilverlightの開発チームを統率する氏のブログでは、次期製品を含む最新の技術をいち早く紹介しています。 ...
現在利用できる別のオプションは、ObjectDataSourceコントロールの使用です。このコントロールは、データアクセス層から、UIコードをよりクリーンに分別し、データコントロールがページングやソートなどの自動機能を提供できるようにします。しかし、データの選択では上手くいっても、双方向のデータバインディングを実施した時はまだ面倒で、簡単な(複雑な型の”深い”バインディングのない)プロパティだけしかサポートしなかったり、(エラー検証なども含む)多くのシナリオを処理するために、多くの複雑なコードを書かなければいけなかったりします。
以降2011/10/05追記
データクラスの代わりに型指定したDataRowが使えるのでは?
DataRowは引数のないPublicなコンストラクタがないので駄目です。
ObjectDataSource クラス (System.Web.UI.WebControls)
多階層 Web アプリケーション アーキテクチャで、データ バインド コントロールにデータを提供するビジネス オブジェクトを表します。 ...
ObjectDataSource コントロールは、リフレクションを使用してビジネス オブジェクトのインスタンスを作成し、作成したインスタンスに対してメソッドを呼び出してデータを更新、挿入、および削除します。