【WPF】SQLite から Linq でデータを取得してDataGrid に表示してみる

公開日:2019-02-04
最終更新:2019-02-04
※この記事は外部サイト(https://www.doraxdora.com/blog/2017/06/09/...)からのクロス投稿です

[email protected]#で、その他リソースの外部ファイル化をやろうかと思ったのですが、
DataGridにちゃんとデータベースからデータを表示したかったのでちょっと寄り道。

とりあえずサンプルなんかで無料のデータベースを使うのあれば SQLite で十分なので、
SQLiteを使ってデータの検索、DataGridへの表示をやってみようと思います。

プログラムは前回のものを修正します。
【WPF】スタイルをCSSみたいに外部ファイルに定義する

まずは SQLite に接続するための準備から。

Nuget でパッケージをダウンロード


ソリューションエクスプローラーからプロジェクトを選択、右クリックし
「Nuget パッケージの管理」を選択します。

Nuget パッケージ管理画面が表示されるので、
検索窓に「SQLite」を入力し、「System.Data.SQLite」を選択、
インストールボタンをクリックします。

変更の確認ダイアログが表示されるので、
「OK」ボタンをクリックします。

出力ビューに「終了」が出力されればOKです。

ソリューションエクスプローラーの「参照」を開き
System.Data.* が追加されていることが確認できれば追加完了です。

ビルド


一度ビルドを実行します。
上部メニューの「ビルド」>「ソリューションのリビルド」を選択します。

プロジェクトのディレクトリ>bin>Target>x86 、x64 に「SQLite.Interop.dll」が
出力されていることを確認します。

起動時にテーブルを作成する

プログラム修正


アプリケーション起動時に、テーブルを作成するようにプログラムを修正します。

MainWindows.xaml.cs

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    using System.Threading.Tasks;  
    using System.Windows;  
    using System.Windows.Controls;  
    using System.Windows.Data;  
    using System.Windows.Documents;  
    using System.Windows.Input;  
    using System.Windows.Media;  
    using System.Windows.Media.Imaging;  
    using System.Windows.Navigation;  
    using System.Windows.Shapes;  

    // SQLite利用のため追加  
    using System.Data.SQLite;  

    namespace WpfApp1  
    {  
        /// <summary>  
        /// MainWindow.xaml の相互作用ロジック  
        /// </summary>  
        public partial class MainWindow : Window  
        {  
            public MainWindow()  
            {  
                InitializeComponent();  
                // SampleDb.sqlite を作成(存在しなければ)  
                using (var conn = new SQLiteConnection("Data Source=SampleDb.sqlite"))  
                {  
                    // データベースに接続  
                    conn.Open();  
                    // コマンドの実行  
                    using (var command = conn.CreateCommand())  
                    {  
                        // テーブルが存在しなければ作成する  
                        // 種別マスタ  
                        StringBuilder sb = new StringBuilder();  
                        sb.Append("CREATE TABLE IF NOT EXISTS MSTKIND (");  
                        sb.Append("  KIND_CD NCHAR NOT NULL");  
                        sb.Append("  , KIND_NAME NVARCHAR");  
                        sb.Append("  , primary key (KIND_CD)");  
                        sb.Append(")");  

                        command.CommandText = sb.ToString();  
                        command.ExecuteNonQuery();  

                        // 猫テーブル  
                        sb.Clear();  
                        sb.Append("CREATE TABLE IF NOT EXISTS TBLCAT (");  
                        sb.Append("  NO INT NOT NULL");  
                        sb.Append("  , NAME NVARCHAR NOT NULL");  
                        sb.Append("  , SEX NVARCHAR NOT NULL");  
                        sb.Append("  , AGE INT DEFAULT 0 NOT NULL");  
                        sb.Append("  , KIND_CD NCHAR DEFAULT 0 NOT NULL");  
                        sb.Append("  , FAVORITE NVARCHAR");  
                        sb.Append("  , primary key (NO)");  
                        sb.Append(")");  

                        command.CommandText = sb.ToString();  
                        command.ExecuteNonQuery();  

                    }  
                    // 切断  
                    conn.Close();  
                }  
            }  
        }  
    }

 

アプリケーションの実行


上部メニューの開始ボタンをクリックし、アプリケーションを実行すると
「MSTKIND」、「TBLCAT」テーブルが作成されます。

SQLite のデータベースを操作できるツール等で、テーブルが作成されていることを確認します。

今回は Firefox のアドオン「SQLite Manager」で確認しました。

データの追加


次のデータをツール、もしくはコマンドラインから追加します。
    INSERT INTO MSTKIND VALUES ("01", "キジトラ");  
    INSERT INTO MSTKIND VALUES ("02", "長毛種(不明)");  
    INSERT INTO MSTKIND VALUES ("03", "ミケ(っぽい)");  
    INSERT INTO MSTKIND VALUES ("04", "サビ");  
    INSERT INTO MSTKIND VALUES ("09", "その他");  
    INSERT INTO TBLCAT VALUES('1','そら','♂','6','01','犬の人形');  
    INSERT INTO TBLCAT VALUES('2','りく','♂','5','02','人間');  
    INSERT INTO TBLCAT VALUES('3','うみ','♀','4','03','高級ウェットフード');  
    INSERT INTO TBLCAT VALUES('4','こうめ','♀','2','04','横取りフード');

今度はコマンドラインから追加してみました。

更に SQLite Manager にて確認。

Linq で データを取得、設定する

Linqとは

オブジェクトやデータベース、データセット、エンティティ、XML文書など、アプリケーションで扱うさまざまなデータソースに対して、統一的な手段でアクセスするしくみ

Linq用パッケージの追加


Linqを利用するため、ライブラリの追加を行います。

ソリューションエクスプローラに表示されている「参照」を右クリックし
参照の追加画面を開きます。

「System.Data.Linq」を検索し、表示されたものを選択、「OK」ボタンをクリックします。

プログラム修正

クラス追加


種別クラス

Kind.cs

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading.Tasks;  

using System.Data.Linq.Mapping;  

namespace WpfApp1  
{  
    [Table(Name = "mstkind")]  
    public class Kind  
    {  
        [Column(Name = "kind_cd", IsPrimaryKey = true)]  
        public String KindCd { get; set; }  
        [Column(Name = "kind_name")]  
        public String KindName { get; set; }  
    }  
}

猫データクラス

Cat.cs

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading.Tasks;  

using System.Data.Linq.Mapping;  

namespace WpfApp1  
{  
    [Table(Name = "tblcat")]  
    public class Cat  
    {  

        [Column(Name = "no", IsPrimaryKey = true)]  
        public int No { get; set; }  
        [Column(Name = "name")]  
        public String Name { get; set; }  
        [Column(Name = "sex")]  
        public String Sex { get; set; }  
        [Column(Name = "age")]  
        public int Age { get; set; }  
        [Column(Name = "kind_cd")]  
        public String Kind { get; set; }  
        [Column(Name = "favorite")]  
        public String Favorite { get; set; }  
    }  
}

 

宣言の追加


MainWindow.xaml.cs

Linqを利用するためにパッケージ利用宣言を追加
(System.Data.Linq.Mapping)

省略  
.  
.  

using System.Data.SQLite;   

using System.Data.Linq; // ←を追記する  
using System.Data.Linq.Mapping; // ←を追記する  

namespace WpfApp1 {  
省略  
}

データ取得処理の追加


「MainWindow」メソッドに次の記述を追加

MainWindow.xaml.cs

                    // 種別マスタを取得してコンボボックスに設定する  
                    using (DataContext con = new DataContext(conn))  
                    {  
                        // データを取得  
                        Table<Kind> mstKind = con.GetTable<Kind>();  
                        IQueryable<Kind> result = from x in mstKind orderby x.KindCd select x;  

                        // 最初の要素は「指定なし」とする  
                        Kind empty = new Kind();  
                        empty.KindCd = "";  
                        empty.KindName = "指定なし";  
                        var list = result.ToList();  
                        list.Insert(0, empty);  

                        // コンボボックスに設定  
                        this.search_kind.ItemsSource = list;  
                        this.search_kind.DisplayMemberPath = "KindName";  
                    }

新規メソッドの追加(クリックイベント)

            /// <summary>  
            /// 検索ボタンクリックイベント.  
            ///   
            /// </summary>  
            /// <param name="sender"></param>  
            /// <param name="e"></param>  
            private void search_button_Click(object sender, RoutedEventArgs e)  
            {  
                using (var conn = new SQLiteConnection("Data Source=SampleDb.sqlite"))  
                {  
                    conn.Open();  

                    // 猫データ一覧を取得して DataGrid に設定  
                    using (DataContext con = new DataContext(conn))  
                    {  
                        String searchName = this.search_name.Text;  
                        String searchKind = (this.search_kind.SelectedValue as Kind).KindCd;  

                        // データを取得  
                        Table<Cat> tblCat = con.GetTable<Cat>();  

                        // サンプルなので適当に組み立てる  
                        IQueryable<Cat> result;  
                        if (searchKind == "") {  
                            // 名前は前方一致のため常に条件していしても問題なし  
                            result = from x in tblCat  
                                     where x.Name.StartsWith(searchName)  
                                     orderby x.No  
                                     select x;  
                        }  
                        else  
                        {  
                            result = from x in tblCat  
                                     where x.Name.StartsWith(searchName) &amp; x.Kind == searchKind  
                                     orderby x.No  
                                     select x;  

                        }  
                        this.dataGrid.ItemsSource = result.ToList();  
                    }  

                    conn.Close();  
                }  

            }

ビューの修正


検索ボタンにクリックイベントを追加します。

MainWindows.xaml

    <Button x:Name="search_button" Content="検索" Margin="432,12,0,0" Style="{StaticResource btn-normal}" Click="search_button_Click"/>

起動


全件検索


全データが表示されました。

名前指定検索


名前を指定したので、そらのみ表示されました。

種別指定検索


みけっぽい、「うみ」のみ表示されました。

存在しない組み合わせで検索


こうめはサビなので、なにも表示されません。

まとめ


ひとまず、DataGrid に表示できました。
サンプルなのでソースはまあまあ適当ですが、なんとなく使い方がわかってきました。
(実は Linq も初)

日々新しい技術が出てくるのでついていくのが大変ですね。
頑張ります。

次回(未定)は Log4net を使ってみたいと思います。

ではでは。

ソースはこちら

GitHub

記事が少しでもいいなと思ったらクラップを送ってみよう!
0
+1
@doraxdoraの技術ブログ 主に Java, C#, Python, Javascript の記事を載せていく予定。

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする