酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows PhoneでLINQ to SQLを使ってレコードの追加と削除をおこなう

Windows Phone OS 7.1からアプリケーションの分離ストレージ領域にローカルデータベースファイルを作成できるようになりました。アプリケーションからのデータベース操作はSQLは使用できません。LINQ to SQLを介してデータベース操作をおこないます。

基本的な使い方を習得する為に、Addボタンをタップするとエンティティを追加し、ListBox上のアイテムを選択するとエンティティを削除するアプリケーションを作成してみましょう。

前回(LINQ to SQLを使ってデータベースを作成する)ではデータコンテキスト定義の仕方とデータベースの作り方をやりました。今回は、エンティティの追加と削除をやってみましょう。

上手くエンティティの追加が出来ると、Addボタンをタップする度に下図のようにタイムスタンプが増えていくようになります。


エンティティ(レコード)の挿入

Addボタンがタップされるとエンティティの挿入を行います。

下記のコードではエンティティの作成、エンティティの追加、データベースへの変更の確定を行います。

SampleItemオブジェクトを生成して、データコンテキストのSampleTableテーブルにSampleItemオブジェクトを追加しています。SubmitChangesメソッドが呼ばれるとデータの挿入が確定し、データベースが保存されます。

ListBoxコントロールで表示させているコレクションsampleIemsに対してSampleItemオブジェクトを追加すると、ListBoxのアイテムも1つ追加されます。

        // データの挿入をおこなう
        private void btnAdd_Click(object sender, System.EventArgs e) {

            using (var db = new SampleDataContext()) {

                // データベースへ格納するアイテムを生成
                var item = new SampleItem { Timestamp = DateTime.Now };

                // データベースへデータを挿入する
                db.SampleTable.InsertOnSubmit(item);

                // ListBoxに表示しているコレクションに追加
                sampleIems.Add(item);

                // データの挿入を確定する(データベースを保存する)
                db.SubmitChanges();
            }
        }

データコンテキストが破棄されるまでにSubmitChangesメソッドを呼ばないと、それまでのデータベース操作が反映されませんので気を付けてください。

エンティティ(レコード)の削除

ListBoxコントロールで選択されたエンティティの削除を行います。

下記のコードでは選択されたアイテムからデータベースの削除対象を取得し、DeleteOnSubmitメソッドでデータベースからデータを削除しています。

ListBoxコントロールで表示させているコレクションsampleIemsから、削除対象のSampleItemオブジェクトを削除すると、ListBoxのアイテムも1つ削除されます。

        // ListBoxで選択されたアイテムをデータベースから削除する
        private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {

            var control = sender as ListBox;

            // 選択時のアイテムがSampleItem型でなければ処理しない
            var selectedItem = control.SelectedItem as SampleItem;
            if (selectedItem == null) {
                return;
            }

            using (var db = new SampleDataContext()) {
                
                // データベースに格納しているアイテムから消したいアイテムを取り出す
                var deleteItems = db.SampleTable.Single(item => item.Timestamp == selectedItem.Timestamp);

                // データベースからデータを削除する
                db.SampleTable.DeleteOnSubmit(deleteItems);

                // ListBoxに表示しているコレクションから削除
                sampleIems.Remove(selectedItem);

                // データの削除を確定する(データベースを保存する)
                db.SubmitChanges();
            }
        }

こちらもデータコンテキストが破棄されるまでにSubmitChangesメソッドを呼ばないと、それまでのデータベース操作が反映されませんので気を付けてください。

XAMLの定義

最後に使用したXAMLです。

<phone:PhoneApplicationPage 
    x:Class="LinqToSqlTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="696"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot は、すべてのページ コンテンツが配置されるルート グリッドです-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel は、アプリケーション名とページ タイトルを格納します-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="SOFTBUILD" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="linq to sql test" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <!--ContentPanel - 追加コンテンツをここに入力します-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        	<ListBox Name="listBox" SelectionChanged="listBox_SelectionChanged">
        		<ListBox.ItemTemplate>
				<DataTemplate>
					<Grid Height="48">
						<TextBlock Text="{Binding Timestamp}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
					</Grid>
					
				</DataTemplate>
        		</ListBox.ItemTemplate>
        	</ListBox>
        </Grid>
    </Grid>
 
    <!--ApplicationBar の使用法を示すサンプル コード-->
    <phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
            <shell:ApplicationBarIconButton x:Name="btnAdd" 
                                            IconUri="/icons/appbar.add.rest.png" 
                                            Text="add" 
                                            Click="btnAdd_Click"/>
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>

</phone:PhoneApplicationPage>