概要
System.Data.Sqliteでデータベース内のテーブルをデータテーブルを介してDataGridに読み込みます。
DataGrid上で修正してデータベースを更新します。
ここでSQLiteDataAdapterを使用します。
WPFで作成していますが、MVVMな書き方にはなっていません。
XAML, コード
ビュー XAML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<Window x:Class="SysDataSQLiteTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:SysDataSQLiteTest" mc:Ignorable="d" Title="MainWindow" Height="248.5" Width="481.183" Closing="Window_Closing"> <Grid> <StackPanel > <StackPanel > <Menu x:Name="menu" > <MenuItem Header="メニュー" > <MenuItem Header="DBfフォルダを開く" Click="MenuItem_Click" /> </MenuItem> </Menu> </StackPanel> <StackPanel Orientation="Horizontal" Margin="10,10,10,0"> <StackPanel Margin="0,0,10,0" > <TextBox x:Name="textbox_dbpath" Text="./SysDataSQLiteTest.db" Margin="0,0,0,5" /> <TextBox x:Name="textbox_tableName" Text="Proj" Margin="0,0,0,5"/> <Button x:Name="btn_readTable" Content="Tableを読込む(読込んでから更新ボタンで更新)" Click="Btn_readTable_Click" Margin="0,5,0,0"/> <Button x:Name="btn_updateTable" Content="Table更新(SQLiteCommandBuilder)" Click="Btn_updateTable_Click" Margin="0,5,0,5"/> </StackPanel> <StackPanel > <DataGrid x:Name="dataGrid" MinHeight="100" MinWidth="100" Margin="0,0,0,0" ItemsSource="{Binding}"/> </StackPanel> </StackPanel> </StackPanel> </Grid> </Window> |
コード (MainWindow.xaml.cs)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
using System; using System.Windows; namespace SysDataSQLiteTest { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { // クラスのインスタンス Class_sysdataSQLite cl_sysSQL = new Class_sysdataSQLite(); // プロパティ System.Data.DataTable dataTable { get; set; } public MainWindow() { InitializeComponent(); } /// <summary> /// データベース保存フォルダをエクスプローラで開く /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MenuItem_Click(object sender, RoutedEventArgs e) { try { string directoryPath = ""; // フォルダをエクスプローラで開く。 if (textbox_dbpath.Text.StartsWith(".")) { System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex("."); directoryPath = System.IO.Path.GetDirectoryName( regex.Replace(textbox_dbpath.Text, System.Environment.CurrentDirectory, 1)); } else { directoryPath = System.IO.Path.GetDirectoryName(textbox_dbpath.Text); } System.Diagnostics.Process.Start("explorer.exe", directoryPath); } catch (Exception ex) { string message = ""; message = ex.Message; #if DEBUG message = message + Environment.NewLine + ex.ToString(); #endif MessageBox.Show(message); } } /// <summary> /// テーブルを読込む /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Btn_readTable_Click(object sender, RoutedEventArgs e) { try { // データベースからテーブルを読込み、DataTableを返す。 dataTable = cl_sysSQL.readTable(textbox_dbpath.Text, textbox_tableName.Text); // データグリッドにDataTableをバインド dataGrid.DataContext = dataTable; } catch (Exception ex) { string message = ""; message = ex.Message; #if DEBUG message = message + Environment.NewLine + ex.ToString(); #endif MessageBox.Show(message); } } private void Btn_updateTable_Click(object sender, RoutedEventArgs e) { try { // SQLDataAdapterを用いて変更を反映する。 cl_sysSQL.updateTable(textbox_dbpath.Text, dataTable); } catch (Exception ex) { string message = ""; message = ex.Message; #if DEBUG message = message + Environment.NewLine + ex.ToString(); #endif MessageBox.Show(message); } } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { try { if(cl_sysSQL.connection != null) { cl_sysSQL.connection.Clone(); } } catch (Exception ex) { string message = ""; message = ex.Message; #if DEBUG message = message + Environment.NewLine + ex.ToString(); #endif MessageBox.Show(message); } } } } |
コード (クラス: Class_sysdataSQLite)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
using System; using System.Windows; namespace SysDataSQLiteTest { class Class_sysdataSQLite { // プロパティ // SQLiteConnectionとSQLiteDataAdapterは読込んだテーブルの更新時にも使用するので、disposeさせない。 public System.Data.SQLite.SQLiteConnection connection { get; set; } private System.Data.SQLite.SQLiteDataAdapter dataAdapter { get; set; } /// <summary> /// テーブルをデータテーブルに読込む /// </summary> /// <param name="databasePath">ターゲットデータベースのパス</param> /// <param name="tableName">読込むテーブル名</param> /// <param name="dt">出力先のデータテーブル</param> public System.Data.DataTable readTable( string dbPath, string tableName) { try { System.Data.DataTable dt = new System.Data.DataTable(); string connectionChar = $"Data Source={dbPath}"; connection = new System.Data.SQLite.SQLiteConnection(connectionChar); // データベースに接続 connection.Open(); // うっかりコマンドのインスタンスをusingで括ってしまうとdisposeされてしまい、 // dataAdapter更新時に例外に遭遇するので注意が必要。 // 以下、間違い。 //using (System.Data.SQLite.SQLiteCommand cmd = connection.CreateCommand()) //{ // cmd.CommandText = $"SELECT * FROM {tableName}"; // // DataAdapterの生成 // dataAdapter = new System.Data.SQLite.SQLiteDataAdapter(cmd); // // データベースからデータを取得 // dataAdapter.Fill(dt); //} // 以上。間違い。 //テーブルとテーブルに含まれる全レコード選択 System.Data.SQLite.SQLiteCommand cmd = connection.CreateCommand(); cmd.CommandText = $"SELECT * FROM {tableName}"; // DataAdapterの生成 dataAdapter = new System.Data.SQLite.SQLiteDataAdapter(cmd); // DataAdapterの生成 別の書き方 // dataAdapter = new System.Data.SQLite.SQLiteDataAdapter($"SELECT * FROM {tableName}", connection); // データベースからデータを取得 dataAdapter.Fill(dt); return dt; } catch (Exception ex) { string message = ""; message = ex.Message; #if DEBUG message = message + Environment.NewLine + ex.ToString(); #endif MessageBox.Show(message); return null; } } /// <summary> /// テーブルを更新する。 /// </summary> /// <param name="databasePath">ターゲットデータベースのパス</param> /// <param name="tableName">ターゲットのテーブル名</param> public void updateTable(string dbPath, System.Data.DataTable dataTable) { try { using (System.Data.SQLite.SQLiteTransaction trans = connection.BeginTransaction()) { System.Data.SQLite.SQLiteCommandBuilder builder = new System.Data.SQLite.SQLiteCommandBuilder(dataAdapter); builder.SetAllValues = true; builder.ConflictOption = System.Data.ConflictOption.OverwriteChanges; builder.GetUpdateCommand(); string message = builder.GetUpdateCommand().CommandText + Environment.NewLine + Environment.NewLine + builder.GetInsertCommand().CommandText + Environment.NewLine + Environment.NewLine + builder.GetDeleteCommand().CommandText + Environment.NewLine + Environment.NewLine; int ret = dataAdapter.Update(dataTable); trans.Commit(); message += $"{ret}件変更完了"; MessageBox.Show(message); } } catch (Exception ex) { string message = ""; message = ex.Message; #if DEBUG message = message + Environment.NewLine + ex.ToString(); #endif MessageBox.Show(message); } } } } |
補足
連載記事
- C#でSystem.Data.Sqliteを使用する ー 導入編 ー | Invisible Works
- [] System.Data.Sqliteをインストールする。 | Invisible Works
- [] System.Data.Sqliteでデータベースを作成する。 | Invisible Works
- [] System.Data.Sqliteでデータベースにデータテーブルを作成する。 | Invisible Works
- [] System.Data.Sqliteでデータベースを読み込んでDataGridに表示する | Invisible Works
- [] System.Data.Sqliteでデータベースのテーブルに行(レコード)を追加する。 | Invisible Works
- [] System.Data.Sqliteでデータベース内のテーブルを、データテーブルを介してDataGridに読み込み、更新する (DataAdapterを使用) | Invisible Works
- System.Data.Sqliteでテーブル間のリレーションシップを設定する。
- [] [C#][WPF][SQLite] System.Data.Sqliteでテーブル間の結合してデータを抽出する。- 内部結合編 – | Invisible Works
- [] [C#][WPF][SQLite] System.Data.Sqliteでテーブル間の結合してデータを抽出する。- 外部結合編 – | Invisible Works
- [] [C#][WPF][SQLite] System.Data.Sqliteでテーブル間の結合してデータを抽出する。- 交差結合編 – | Invisible Works
- [] [C#][WPF][SQLite] System.Data.Sqliteで中間テーブルを利用して、1対多、多対多のテーブル結合を行う。 | Invisible Works
- [to be drafted] トランザクション処理したい
コメント