プロジェクトを作成
mkdir <プロジェクト>
cd <プロジェクト>
dotnet new console -f net6.0
dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.Sqlite.Core
dotnet add package SQLitePCLRaw.bundle_green
ソースファイル
ファイル名:Program.cs
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema;
namespace ConsoleEntityFramework;
public class LastChange
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int Id {get; set;}
public string Date {get; set;} = "";
public string Memo {get; set;} = "";
}
public class SqliteDbContext : DbContext
{
public DbSet<LastChange> LastChange => Set<LastChange>();
public string DbPath {get; set;} = "";
public SqliteDbContext()
{
DbPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "/sample.db";
Console.WriteLine($"Path:{DbPath}");
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) =>
optionsBuilder.UseSqlite($"Data Source={DbPath}");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<LastChange>().ToTable("LastChange");
}
}
public class Program
{
public static void Main(string[] args)
{
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
var db = new SqliteDbContext();
// テーブル作成
db.Database.EnsureCreated();
//var sql = @"CREATE TABLE Record ( Id INTEGER NOTULL PRIMARY KEY, Name TEXT NOT NULL);";
//db.Database.ExecuteSqlRaw(sql);
// レコード件数が0の場合
if (!db.LastChange.Any())
{
// 追加
db.Add(new LastChange{Date = DateTime.Now.ToString("yyyy/MM/dd"),Memo="OilChange"});
db.Add(new LastChange{Date = DateTime.Now.ToString("yyyy/MM/dd"),Memo="Haircut"});
db.SaveChanges();
}
// 表示
foreach(var r in db.LastChange)
{
Console.WriteLine("{0} {1} {2}", r.Id, r.Date, r.Memo );
}
// 更新
var f = db.LastChange.Single(x => x.Memo == "Haircut");
if (f != null)
{
f.Memo = "Sanpatu";
db.SaveChanges();
}
// 表示
foreach(var r in db.LastChange)
{
Console.WriteLine("{0} {1} {2}", r.Id, r.Date, r.Memo );
}
// 削除
foreach(var r in db.LastChange)
{
db.LastChange.Remove(r);
db.SaveChanges();
}
}
}
実行
dotnet run
結果
1 2023/06/20 OilChange 2 2023/06/20 Haircut 1 2023/06/20 OilChange 2 2023/06/20 Sanpatu
二回目
3 2023/06/20 OilChange 4 2023/06/20 Haircut 3 2023/06/20 OilChange 4 2023/06/20 Sanpatu
学習したこと
SqliteDbContext.OnModelCreating()内でテーブルの作成している。db.Database.EnsureCreated()で呼び出される模様。
[DatabaseGenerated(DatabaseGeneratedOption.Identity)][Key]をセットするとSqliteの場合PRIMARY KEYでAUTOINCREMENTな項目になる模様(AddでIdをセットしていませんが、取得すると値が採番されていることから)。
追記20241007:
アプリケーションのデータ保存にオブジェクトをシリアライズして、JSONやXML形式のテキストファイルとして保存していましたが、EntityFrameworkを使ってデータベースに保存する方法もよさそうな感じがします。
追記20250222
EntityFrameworkはORMにカテゴライズされます。
通常データベースにアクセスする場合SQLを使いますが、SQLで取得したデータをC#のオブジェクトに変換したり、逆にC#のオブジェクトのデータをもとにデータベースのテーブルを追加、更新、削除などを行うことになります。
その場合SQLとC#間でデータを相互変換するコードを書く必要があり、それを自動化する仕組みがORMでありMicrosoftの実装の一つとしてEntityFrameworkがあります。
サンプルプログラムのclass LastChange
のLastChangeというテーブルで、プロパティがテーブルの項目に相当します。KeyやDatabaseGenerated
など通常のC#ではあまりお目にかからない構文がありますが、こちらはテーブル定義の主キーや自動採番を表します。
こちらのクラスを介して、テーブルの作成から追加・更新・削除・参照などをSQLを記述することなくC#のオブジェクトとしてデータベースを操作することが出来ます。
サンプルプログラムで参照はforeachですべてのレコードを取得しています。、
更新する場合、更新するレコードを絞り込む必要がありますが、Single()で条件を指定し1件のレコードに絞り込み、その後項目を書き換えSaveChanges()
でデータを更新します。
削除はRemove()
で削除し、SaveChanges()
でテーブルに適用します。
コメント