SQL Server Compact 3.5 を利用するアプリでの DB 構築と項目の追加(その2)

SQL Server Compact 3.5 を利用するアプリでの DB 構築と項目の追加(その1)」の続きです。前回の方針にそってコードを書いていきます。
まずは、「初期 DB 作成部分を作る」です。

MainWindow.xaml です。

<Window x:Class="ProductVupWithSdfTest003.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="380" Width="525">
    <StackPanel>
        <TextBlock
            Text="SQL Server Compact の初期設定及び追加設定のテスト"
            FontSize="14" Margin="10 10 10 5" HorizontalAlignment="Center" />
        <TextBlock
            Text="(その3・LINQ to SQL を使用)"
            FontSize="14" Margin="10 5 10 10" HorizontalAlignment="Center" />
        <Button
            Content="初期設定" Name="BtnInit" Margin="5" Padding="10 5" Click="BtnInit_Click" />
        <Button
            Content="追加設定" Name="BtnAlter" Margin="5" Padding="10 5" Click="BtnAlter_Click" />
        <Border BorderBrush="Black" BorderThickness="1" CornerRadius="0" Padding="0" />
        <Button
            Content="顧客情報取得" Name="BtnGetCustomer" Margin="5" Padding="10 5" Click="BtnGetCustomer_Click" />
        <Button
            Content="販売記録取得" Name="BtnGetSale" Margin="5" Padding="10 5" Click="BtnGetSale_Click" />
        <Button
            Content="顧客情報追加" Name="BtnAddCustomer" Margin="5" Padding="10 5" Click="BtnAddCustomer_Click" />
        <Border BorderBrush="Black" BorderThickness="1" CornerRadius="15" Padding="10">
            <TextBlock Name="TbkResult" FontSize="11" />
        </Border>
    </StackPanel>
</Window>

次に MainWindow.xaml.cs です。「初期設定」ボタンのクリック時の処理だけ記述します。

using System;
using System.Text;
using System.Windows;
using System.Windows.Input;

namespace ProductVupWithSdfTest003
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();
        }
        private void BtnInit_Click(object sender, RoutedEventArgs e)
        {
            this.Cursor = Cursors.Wait;
            DbInit.Init();

            this.Cursor = Cursors.Arrow;
        }

        private void BtnAlter_Click(object sender, RoutedEventArgs e)
        {
        }

        private void BtnGetCustomer_Click(object sender, RoutedEventArgs e)
        {
        }

        private void BtnAddCustomer_Click(object sender, RoutedEventArgs e)
        {
        }

        private void BtnGetSale_Click(object sender, RoutedEventArgs e)
        {
        }
    }
}

次に DbInit.cs ですが、その前に「System.Data.SqlServerCe」の参照設定を行います。
ソリューション エクスプローラーのプロジェクトを右クリックして「参照の追加」を選択します。
参照の追加ウィンドウの「.NET」タブに表示されているコンポーネント名から「System.Data.SqlServerCe」を選択して OK ボタンをクリックします。これで System.Data.SqlServerCe が使えるので、DbInit.cs を記述します。接続文字列の「パスワード」のところは、適当なものを設定してください。この接続文字列では、実行可能ファイルの生成フォルダ(Debug 構成では bin\debug)に TestDb.sdf ファイルが作られます。

using System.Data.SqlServerCe;

namespace ProductVupWithSdfTest003
{
    static internal class DbInit
    {
        private const string conStr =
            @"Data Source='|DataDirectory|TestDb.sdf'; Password=パスワード;;

        static public string ConnectionString
        {
            get { return conStr; }
        }

        static public void Init()
        {
            using (var connect = new SqlCeConnection(conStr))
            {
                if (System.IO.File.Exists(connect.DataSource))
                    System.IO.File.Delete(connect.DataSource);  // DB ファイルが存在していたら削除する
            }

            using (var eng = new SqlCeEngine(conStr))
            {
                eng.CreateDatabase();
            }

            using (var connect = new SqlCeConnection(conStr))
            {
                connect.Open();
                try
                {
                    var sqlStr0 = "CREATE TABLE Manages (" +
                                    "ManageId int IDENTITY (1, 1) PRIMARY KEY, " +
                                    "DataVersion nvarchar (10)" +
                                    ")";
                    var insert0 = "INSERT INTO Manages (DataVersion) VALUES ('1.0')";
                    var sqlStr1 = "CREATE TABLE Customers (" +
                                    "CustomerId int IDENTITY (1, 1) PRIMARY KEY, " +
                                    "CustomerName nvarchar (50)" +
                                    ")";
                    var insert1 = "INSERT INTO Customers (CustomerName) VALUES ('カスタマー1')";
                    var sqlStr2 = "CREATE TABLE Products (" +
                                    "ProductId int IDENTITY (1, 1) PRIMARY KEY, " +
                                    "ProductName nvarchar (50)" +
                                    ")";
                    var insert2 = "INSERT INTO Products (ProductName) VALUES ('商品1')";
                    var sqlStr3 = "CREATE TABLE Sales (" +
                                    "SaleId int IDENTITY (1, 1) PRIMARY KEY, " +
                                    "CustomerId int, " +
                                    "ProductId int, " +
                                    "Quantity int, " +
                                    "FOREIGN KEY (CustomerId) REFERENCES Customers(CustomerId), " +
                                    "FOREIGN KEY (ProductId) REFERENCES Products(ProductId)" +
                                    ")";
                    var insert3 = "INSERT INTO Sales (CustomerId, ProductId, Quantity) " +
                                    "VALUES (1, 1, 5)";
                    using (var command = connect.CreateCommand())
                    {
                        command.CommandText = sqlStr0;
                        command.ExecuteNonQuery();
                        command.CommandText = insert0;
                        command.ExecuteNonQuery();
                        command.CommandText = sqlStr1;
                        command.ExecuteNonQuery();
                        command.CommandText = insert1;
                        command.ExecuteNonQuery();
                        command.CommandText = sqlStr2;
                        command.ExecuteNonQuery();
                        command.CommandText = insert2;
                        command.ExecuteNonQuery();
                        command.CommandText = sqlStr3;
                        command.ExecuteNonQuery();
                        command.CommandText = insert3;
                        command.ExecuteNonQuery();
                    }
                }
                finally
                {
                    connect.Close();
                }
            }
        }
    }
}

これで DB 作成ができるので、実行して「初期設定」ボタンをクリックして、DB を作成したら終了させます。ここまでで、「初期 DB 作成部分を作る」は完了です。

次は「作成した DB から dbml ファイルを生成し、プロジェクトに追加する」です。実行可能ファイルの生成フォルダ(Debug 構成では bin\debug)に TestDb.sdf ファイルが作られているので、このファイルから LINQ to SQL を使うのに必要な dbml ファイルを生成します。生成には sqlmetal コマンドを利用するので、Visual Studio コマンドプロンプトを起動します(開発ツールへのパスが設定された状態で起動するので、コマンド起動の際にパスの指定が不要です)。スタートボタンから Microsoft Visual Studio 2010 Express を選択して Visual Studio コマンドプロンプトを起動させます。

TestDb.sdf のあるフォルダへカレントフォルダを移動させる(cd TestDb.sdf のあるフォルダのフルパス)か、適当なフォルダ(c:\Work など)を作ってそこに TestDb.sdf をコピーしてから「cd c:\Work」と叩くかして、カレントフォルダに TestDb.sdf がある状態にしてから「sqlmetal /password:パスワード /dbml:TestDb.dbml TestDb.sdf」とコマンド入力します(パスワードは設定したパスワードで置き換えてください)。

次に生成された TestDb.dbml ファイルをプロジェクトに追加します。ソリューション エクスプローラーのプロジェクトを右クリックして「追加」から「既存の項目」を選択します。既存の項目の追加ウィンドウが表示されるので、ファイル名の右側に表示されている選択するファイルの種類を「すべてのファイル」にしてから、先程のフォルダに移って TestDb.dbml ファイルを選択して「追加」ボタンをクリックします。
プロジェクトに追加された TestDb.dbml ファイルを開くと、外部キー制約が反映された状態になっているのが確認できます。ここで、お約束の「テーブル名の複数形からクラス名の単数形化」を行います。「Customers」をダブルクリックして名称変更モードにして「Customer」にして Enter キーを押下します(Sales, Products, Manages も同様に)。

変更が終わったら保存します。これで LINQ to SQL を使うのに必要なテーブル等のクラスが生成された状態になっています。

次は「LINQ to SQL を用いてアプリケーションを構築する」です。
DbService.cs を作成します。

using System.Collections.Generic;
using System.Linq;

namespace ProductVupWithSdfTest003
{
    internal class DbService
    {
        public DbService()
        {
        }

        public List<Customer> FindCustomers()
        {
            using (var testDb = new TestDb(DbInit.ConnectionString))
            {
                return testDb.Customer.ToList();
            }
        }

        public void AddCustomer(Customer customer)
        {
            using (var testDb = new TestDb(DbInit.ConnectionString))
            {
                testDb.Customer.InsertOnSubmit(customer);
                testDb.SubmitChanges();
            }
        }

        public IList<Sale> FindSales()
        {
            var result = new List<Sale>();
            using (var testDb = new TestDb(DbInit.ConnectionString))
            {
                foreach (var n in testDb.Sale)
                {
                    result.Add(new Sale {
                        SaleId = n.SaleId,
                        CustomerId = n.CustomerId,
                        ProductId = n.ProductId,
                        Quantity = n.Quantity,
                        Customer = n.Customer,
                        Product = n.Product
                    });
                }
            }
            return result;
        }
    }
}

次に MainWindow.Xaml.cs を変更します。

//
        private DbService _service;

        public MainWindow()
        {
            InitializeComponent();

            _service = new DbService();
        }
//
        private void BtnGetCustomer_Click(object sender, RoutedEventArgs e)
        {
            this.Cursor = Cursors.Wait;

            var temp = new StringBuilder();
            _service.FindCustomers().ForEach(n =>
            {
                temp.AppendFormat("{0}: {1}\r\n", n.CustomerId, n.CustomerName);
            });
            this.TbkResult.Text = temp.ToString();

            this.Cursor = Cursors.Arrow;
        }

        private void BtnAddCustomer_Click(object sender, RoutedEventArgs e)
        {
            this.Cursor = Cursors.Wait;

            var customer = new Customer
            {
                CustomerName = "追加顧客",
            };
            _service.AddCustomer(customer);

            this.Cursor = Cursors.Arrow;
        }

        private void BtnGetSale_Click(object sender, RoutedEventArgs e)
        {
            this.Cursor = Cursors.Wait;

            var temp = new StringBuilder();
            foreach (var n in _service.FindSales())
            {
                temp.AppendFormat("ID:{0}, Customer:{1}, Product:{2}, Quantity:{3}\r\n", 
                    n.SaleId, n.Customer.CustomerName, n.Product.ProductName, n.Quantity);
            }
            this.TbkResult.Text = temp.ToString();

            this.Cursor = Cursors.Arrow;
        }

これで初期状態の完成になります。「販売記録取得」ボタンをクリックすると次のように表示されます。

次は DB の構成変更ですが、長くなったので(その3)に続きます。


SQL Server Compact 3.5 を利用するアプリでの DB 構築と項目の追加(その2)」への2件のフィードバック

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です