WPF アプリから SQLite(System.Data.SQLite) を使ってデータを登録(INSERT)する最小構成のサンプルです。
MVVM 構成+DI(依存性注入)+ SQLite の基本を理解するのに最適です。
🎯 目的
- SQLite データベースにレコードを登録する
- MVVM パターンで責務を分離
- System.Data.SQLite を使用(Microsoft.Data.Sqlite ではない)
📂 プロジェクト構成
WpfMinimalMvvm/
├── Models/
│ └── Employee.cs
├── IServices/
│ └── IEmployeeRepository.cs
├── Services/
│ └── SqliteEmployeeRepository.cs
├── ViewModels/
│ └── MainViewModel.cs
└── MainWindow.xaml
└── MainWindow.xaml.cs
└── App.xaml / App.xaml.cs
🧱 Models/Employee.cs
namespace WpfMinimalMvvm.Models
{
public class Employee
{
public int Id { get; set; } // 自動採番
public string Name { get; set; } = ""; // 必須
public int Age { get; set; } // 例:年齢
public bool IsActive { get; set; } // 例:在籍
}
}
🧩 IServices/IEmployeeRepository.cs
using System.Threading.Tasks;
using WpfMinimalMvvm.Models;
namespace WpfMinimalMvvm.IServices
{
public interface IEmployeeRepository
{
Task<int> InsertAsync(Employee employee);
}
}
⚙️ Services/SqliteEmployeeRepository.cs
using System.Data.SQLite;
using System.IO;
using WpfMinimalMvvm.IServices;
using WpfMinimalMvvm.Models;
namespace WpfMinimalMvvm.Services
{
public class SqliteEmployeeRepository : IEmployeeRepository
{
private readonly string _dbPath;
public SqliteEmployeeRepository()
{
// コメント:実行フォルダに app.db を作成
_dbPath = Path.Combine(Directory.GetCurrentDirectory(), "app.db");
// コメント:初回のみテーブル作成
using (var cn = new SQLiteConnection($"Data Source={_dbPath};Version=3;"))
{
cn.Open();
using (var cmd = cn.CreateCommand())
{
cmd.CommandText = @"
CREATE TABLE IF NOT EXISTS Employees(
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Name TEXT NOT NULL,
Age INTEGER NOT NULL,
IsActive INTEGER NOT NULL
);";
cmd.ExecuteNonQuery();
}
}
}
public async Task<int> InsertAsync(Employee employee)
{
// コメント:必ず {} を使うスタイル。Name は必須
if (string.IsNullOrWhiteSpace(employee.Name))
{
throw new System.ArgumentException("Name は必須です。");
}
using (var cn = new SQLiteConnection($"Data Source={_dbPath};Version=3;"))
{
await cn.OpenAsync();
using (var cmd = cn.CreateCommand())
{
cmd.CommandText = @"
INSERT INTO Employees (Name, Age, IsActive)
VALUES (@name, @age, @active);
SELECT last_insert_rowid();
";
cmd.Parameters.AddWithValue("@name", employee.Name);
cmd.Parameters.AddWithValue("@age", employee.Age);
cmd.Parameters.AddWithValue("@active", employee.IsActive ? 1 : 0);
var idObj = await cmd.ExecuteScalarAsync();
return System.Convert.ToInt32(idObj);
}
}
}
}
}
🧭 ViewModels/MainViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using WpfMinimalMvvm.IServices;
using WpfMinimalMvvm.Models;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Xml.Linq;
namespace WpfMinimalMvvm.ViewModels
{
public partial class MainViewModel : ObservableObject
{
private readonly IEmployeeRepository _repo;
public MainViewModel(IEmployeeRepository repo)
{
_repo = repo;
}
// 入力項目
[ObservableProperty]
private string name = "";
[ObservableProperty]
private int age = 20;
[ObservableProperty]
private bool isActive = true;
// 結果表示用
[ObservableProperty]
private string message = "準備OK";
// 追加ボタン
[RelayCommand]
private async Task SaveAsync()
{
// 簡易バリデーション
if (string.IsNullOrWhiteSpace(Name))
{
Message = "Name を入力してください。";
return;
}
Employee emp = new Employee
{
Name = Name,
Age = Age,
IsActive = IsActive
};
// DBへ登録
int newId = await _repo.InsertAsync(emp);
Message = $"登録しました(Id={newId})";
}
}
}
🪟 MainWindow.xaml
<Window x:Class="WpfMinimalMvvm.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SQLite Insert Sample" Height="220" Width="360">
<Grid Margin="16">
<StackPanel>
<TextBlock Text="Name" />
<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="Age" Margin="0,8,0,0"/>
<TextBox Text="{Binding Age, UpdateSourceTrigger=PropertyChanged}" />
<CheckBox Content="Is Active" IsChecked="{Binding IsActive}" Margin="0,8,0,0"/>
<Button Content="登録" Command="{Binding SaveCommand}" Margin="0,8,0,0"/>
<TextBlock Text="{Binding Message}" FontSize="14" Margin="0,8,0,0"/>
</StackPanel>
</Grid>
</Window>
🧱 MainWindow.xaml.cs
using System.Text;
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;
using WpfMinimalMvvm.ViewModels;
namespace WpfMinimalMvvm
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow(MainViewModel vm)
{
InitializeComponent();
DataContext = vm;
}
}
}
🚀 App.xaml.cs
using Microsoft.Extensions.DependencyInjection;
using System.Windows;
using WpfMinimalMvvm.IServices; // ← IEmployeeRepository
using WpfMinimalMvvm.Services; // ← SqliteEmployeeRepository
using WpfMinimalMvvm.ViewModels; // ← MainViewModel
namespace WpfMinimalMvvm
{
public partial class App : Application
{
private ServiceProvider? _provider;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var services = new ServiceCollection();
// コメント:SQLiteリポジトリ(Singletonで共有)
services.AddSingleton<IEmployeeRepository, SqliteEmployeeRepository>();
// コメント:ViewModel / View は通常どおり
services.AddTransient<MainViewModel>();
services.AddTransient<MainWindow>();
_provider = services.BuildServiceProvider();
var window = _provider.GetRequiredService<MainWindow>();
window.Show();
}
}
}
✅ SQLite 確認コマンド
cd bin\Debug
et8.0-windows
sqlite3 app.db
.tables
.headers on
.mode column
SELECT * FROM Employees;
⚙️ 使用パッケージ
| パッケージ名 | 用途 |
|---|---|
| System.Data.SQLite.Core | SQLite ADO.NETプロバイダ |
| CommunityToolkit.Mvvm | MVVM用ヘルパ |
| Microsoft.Extensions.DependencyInjection | DIコンテナ |
📘 これで WPF + SQLite の登録機能が完成!