次に、PhotosテーブルからBLOB写真データを読み出すGetAll()とGetByID()メソッドを見ていきます(リスト5を参照してください)。
public static List<Photo> GetAll()
{
SqlConnection cnn = new SqlConnection(strConn);
SqlCommand cmd = new SqlCommand();
List<Photo> photos = new List<Photo>();
byte[] data = new byte[1000];
cmd.CommandText = "select * from photos order by photoid";
cmd.Connection = cnn;
cnn.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Photo p = new Photo();
p.PhotoID = reader.GetInt32(reader.GetOrdinal("PhotoID"));
p.Title = reader.GetString(reader.GetOrdinal("Title"));
p.Description =
reader.GetString(reader.GetOrdinal("Description"));
p.PhotoData =
(byte[])reader.GetValue(reader.GetOrdinal("Photo"));
photos.Add(p);
}
cnn.Close();
return photos;
}
public static Photo GetByID(int photoid)
{
SqlConnection cnn = new SqlConnection(strConn);
SqlCommand cmd = new SqlCommand();
byte[] data = new byte[1000];
cmd.CommandText = "select * from photos
where PhotoID=@photoid";
cmd.Connection = cnn;
SqlParameter pId = new SqlParameter("@photoid", photoid);
cmd.Parameters.Add(pId);
cnn.Open();
SqlDataReader reader = cmd.ExecuteReader();
Photo p = new Photo();
while (reader.Read())
{
p.PhotoID = reader.GetInt32(reader.GetOrdinal("PhotoID"));
p.Title = reader.GetString(reader.GetOrdinal("Title"));
p.Description =
reader.GetString(reader.GetOrdinal("Description"));
p.PhotoData =
(byte[])reader.GetValue(reader.GetOrdinal("Photo"));
}
cnn.Close();
return p;
}
GetAll()メソッドは、Photosテーブルに対してSELECTクエリを発行し、そのすべての行をフェッチします。フェッチした行は、Photoオブジェクトに代入されます。戻り値はPhotoオブジェクトからなるジェネリックリストです。同様にGetByID()メソッドは、指定したPhotoIDに対応するレコードをフェッチし、単一のPhotoオブジェクトを返します。
ここで重要なのは、太字で示されたコード部分です。これがADO.NETにおいてvarbinary(MAX)列を読み出す方法になります。SqlDataReaderのGetValue()メソッドは、データをオブジェクトとして返します。このオブジェクトをバイト配列に型変換します。本稿の後のセクションでは、これと同じ操作を行うためのもっとよい方法を紹介します。
これでクラスが完成しました。次は、Webフォームを作成します。
デフォルトのWebフォームを開き、そこにドラッグ&ドロップでDetailsViewコントロールを配置します。図1に示すように4つのフィールドをDetailsViewコントロールに加えます。

Titleバウンドフィールド(BoundField)は、PhotoクラスのTitleプロパティに対するデータコントロールフィールドです。DescriptionおよびPhotoフィールドはTemplateFieldとなっています。CommandFieldは、DetailsViewに挿入、更新、削除機能を加えるためのものです。これら4つのフィールドのマークアップをリスト6に示します。
<asp:BoundField DataField="Title" HeaderText="Title :" />
<asp:TemplateField HeaderText="Description :">
<EditItemTemplate>
<asp:TextBox ID="TextBox1"
runat="server"
Columns="40"
Rows="5"
Text='<%# Bind("Description") %>'
TextMode="MultiLine">
</asp:TextBox>
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox ID="TextBox1"
runat="server"
Columns="40"
Rows="5"
Text='<%# Bind("Description") %>'
TextMode="MultiLine">
</asp:TextBox>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1"
runat="server"
Text='<%# Bind("Description")
%>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Photo :">
<EditItemTemplate>
<asp:FileUpload ID="FileUpload1"
runat="server" />
</EditItemTemplate>
<InsertItemTemplate>
<asp:FileUpload ID="FileUpload2"
runat="server" />
</InsertItemTemplate>
<ItemTemplate>
<asp:Image ID="Image1"
runat="server"
ImageUrl='<%# Eval("PhotoID","
~/showphoto.aspx?photoid={0}") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ButtonType="Button"
ShowDeleteButton="True"
ShowEditButton="True"
ShowInsertButton="True" />
リスト6から分かるように、Descriptionテンプレートフィールドは、EditItemTemplateとInsertItemTemplateの中に複数行からなるテキストボックスを持ちます。このテキストボックスは、PhotoクラスのDescriptionプロパティに対するものです。Photoテンプレートフィールドは、ItemTemplateの中にImageコントロール、EditItemTemplateとInsertItemTemplateの中にFileUploadコントロールを持つ構造となっています。太字で示された行に着目してください。ImageコントロールのImageUrlプロパティには、本稿の後のセクションで作成するWebフォームである「ShowPhoto.aspx」を設定します。{0}という構文を使用して、クエリ文字列引数としてPhotoIDをこのWebフォームに引き渡す方法にも注意してください。
