ローカルデータベースの利用

Windows Phone でのローカルデータベースの利用についてです.


SilverlightではSQLADO.NETなどでできたのですが,Windows Phone では使えません.
使うものは,Linq to SQL です.
ここでは例として,収支管理のデータベースにしましょう


まず,参照設定にSystem.Data.Linq.dllを追加しましょう

ちょちょっと,ContentPanelに使うものを配置していきます

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
	<TextBlock Margin="8,68,0,0" TextWrapping="Wrap" Text="金額" FontSize="48" HorizontalAlignment="Left" Width="96" Height="63" VerticalAlignment="Top"/>
	<TextBox x:Name="inputMoney_textbox" GotFocus="inputMoney_textbox_GotFocus" InputScope="Number" Height="100" Margin="108,50,8,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="48"/>
	<RadioButton x:Name="income_radiobutton" Content="収入" Height="79" Margin="8,154,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="220" FontSize="29.333" GroupName="IncomeExpense"/>
	<RadioButton x:Name="expense_radiobutton" Content="支出" Height="79" Margin="0,154,8,0" VerticalAlignment="Top" HorizontalAlignment="Right" Width="220" FontSize="29.333" GroupName="IncomeExpense"/>
	<Button x:Name="AddDB_button" Click="AddDB_button_Click" Content="Add DataBase" Margin="8,237,8,284"/>
	<ListBox x:Name="MoneyList_listbox" Height="272" Margin="8,0,8,8" VerticalAlignment="Bottom">
		<Grid Height="55" Width="432">
			<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="収入" Width="85" FontSize="40"/>
			<TextBlock TextWrapping="Wrap" FontSize="40" Margin="89,0,52,0" TextAlignment="Right" Text="0"/>
			<TextBlock TextWrapping="Wrap" Text="円" FontSize="40" Margin="0,0,8,0" HorizontalAlignment="Right" Width="40"/>
		</Grid>
	</ListBox>
</Grid>


このプロジェクト内に,DataBaseのクラスを作成します.ここでは,MyMoneyData.csというクラスを作ります

まずは,MyMoneyData.csの参照に以下のものを加えます.

using System.Data.Linq;
using System.Data.Linq.Mapping;

次に,MyMoneyDataクラスとテーブルに当たるWalletクラスを以下のように作成します

public class MyMoneyData : DataContext  // DataContextを継承
{
	public MyMoneyData()
		: base("isostore:/MyMoney.sdf") // MyMoney.sdfというデータベースファイルを
						// IsolatedStorage内に作成する
	{ }

	public Table<Wallet> myWallet { get { return GetTable<Wallet>(); } } 
						// myWalletというテーブルを作成する
}

[Table]
public class Wallet
{
	[Column(IsPrimaryKey = true, IsDbGenerated = true)]
						// Idをプライマリキーにする
	public int Id { get; set; }

	[Column(CanBeNull = false)]		// valueがnullを許可しない(trueなら許可する)
	public int Sum { get; set; }

	[Column(CanBeNull = false)]
	public bool InOrEx { get; set; }
}

これで準備はOKです.


このアプリの初回起動時にデータベースMyMoney.sdfが作成されるように,App.xaml.cs内に以下のものをApplication_Launchingメソッド内に追加します.

// (たとえば、[スタート] メニューから) アプリケーションが起動するときに実行されるコード
// このコードは、アプリケーションが再アクティブ化済みの場合には実行されません
private void Application_Launching(object sender, LaunchingEventArgs e)
{
	using (var db = new MyMoneyData())
	{
		if (!db.DatabaseExists())
			db.CreateDatabase();
	}
}

これで,データベースが作成されます.
あとは,MainPage.xamlのAddDB_buttonがクリックされた時に,データを追加するようにしましょう.

private void AddDB_button_Click(object sender, RoutedEventArgs e)
{
	if (inputMoney_textbox.Text == "") return;
	
	bool iORe_flag; // income : true, expense : false;
	
	if((bool)income_radiobutton.IsChecked)  // 収支判定
	    iORe_flag = true;
	else
	    iORe_flag = false;

	var money = new MyMoneyData();
	var sum = new Wallet { Sum = Int32.Parse(inputMoney_textbox.Text), InOrEx = iORe_flag };

	money.myWallet.InsertOnSubmit(sum);    // Insertする
	/* 複数を一気にInsertする場合は
	 * money.myWallet.InsertAllOnSubmit(new[] { sum01, sum02, sum03 });
	 */
	money.SubmitChanges();  // SubmitChangesをするまでデータベースには挿入されていない

	ReflectListbox();       // Listboxにデータベースを反映させる
}

private void ReflectListbox()
{
	MoneyList_listbox.Items.Clear();

	var money = new MyMoneyData();
	var query = money.myWallet;
	
	foreach (var sum in query)
	{
	    Grid itemGrid = new Grid()
	    {
		Width = 432,
		Height = 55
	    };
	    TextBlock IorE = new TextBlock()
	    {
		Width = 85,
		HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
		TextWrapping = TextWrapping.Wrap,
		FontSize = 40
	    };
	    if (sum.InOrEx)
		IorE.Text = "収入";
	    else
		IorE.Text = "支出";
	    TextBlock num = new TextBlock()
	    {
		Margin = new Thickness(89, 0, 52, 0),
		TextAlignment = TextAlignment.Right,
		TextWrapping = TextWrapping.Wrap,
		FontSize = 40,
		Text = sum.Sum.ToString()
	    };
	    TextBlock yen = new TextBlock()
	    {
		Width = 40,
		Margin = new Thickness(0, 0, 8, 0),
		HorizontalAlignment = System.Windows.HorizontalAlignment.Right,
		FontSize = 40,
		TextWrapping = TextWrapping.Wrap,
		Text = "円"
	    };
	    itemGrid.Children.Add(IorE);
	    itemGrid.Children.Add(num);
	    itemGrid.Children.Add(yen);

	    MoneyList_listbox.Items.Add(itemGrid);
	}
}

private void inputMoney_textbox_GotFocus(object sender, RoutedEventArgs e)
{
	inputMoney_textbox.SelectAll();
}

※例外処理とかしてないので気を付けてください!
ちょっと色々書きすぎてごちゃごちゃしましたが,重要なのは数行.
テーブルに挿入するところ

var money = new MyMoneyData();
var sum = new Wallet { Sum = Int32.Parse(inputMoney_textbox.Text), InOrEx = iORe_flag };
money.myWallet.InsertOnSubmit(sum);    // Insertする

参照するところ

var money = new MyMoneyData();
var query = money.myWallet;
foreach (var sum in query)
{
	// .... //
	if (sum.InOrEx)
	// .... //
	Text = sum.Sum.ToString()
	// .... //
}

ここだけです.

意外と簡単なので,実践してみてください.
また,データベースはアプリをアンインストールしない限り残ってます.
データベースを削除するには,DeleteDatabase()を使うとよいです.