覚えるのが面倒なのでfluent APIを避けてきましたが、エンティティクラスがPOCOなクラスだと何かと都合が良いことに気が付きましたので、fluent APIを試してみたいと思います。
サンプルプログラム
using Microsoft.EntityFrameworkCore;
namespace EF01;
public class LastChange
{
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>(entity =>
{
// エンティティクラス(LastChange)とテーブルLastChangeを紐づける
entity.ToTable("LastChange");
// 主キーの定義... (複合の場合 e => new {e.A, e.B} )
entity.HasKey(e => e.Id);
// プロパティIdに自動採番属性を付与
entity.Property(e => e.Id)
.ValueGeneratedOnAdd();
// プロパティDateにNOT NULL属性を付与
entity.Property(e => e.Date)
.IsRequired();
// プロパティMemoにNOT NULL属性を付与
entity.Property(e => e.Memo)
.IsRequired();
});
}
}
public class Program
{
public static void Main(string[] args)
{
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
var db = new SqliteDbContext();
// テーブル作成
db.Database.EnsureCreated();
// レコード件数が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.ToList())
{
db.LastChange.Remove(r);
db.SaveChanges();
}
}
}
説明
以前記事に書いたサンプルプログラムをfluent APIで描き直してみました。


C#のConsoleでEntityFramework
EntityFrameworkの基本的な動作を確認するためconsoleプロジェクトでサンプルプログラムを作ってみました。プロジェクトを作成mkdir <プロジェクト>cd <プロジェクト>dotnet new console -f net...
変更点としてエンティティクラスLastChangeで主キーなどの属性が無くなり、代わりにOnModelCreating()に主キーなどの定義が行われるようになっています。
こちらのサンプルコードだと、LastChangeがPOCOなクラスになったとしても特別なメリットは無さそうですが、メンバーがプロパティですのでインターフェイスにすることが出来て、他のクラスに利用したり、単体テストをしたりと再利用がしやすくなると考えられます。
ただ、本格的に再利用を考えて疎結合にする場合、DbContext自体もインタフェースなどで抽象化しないとメリットが出てこないと思われます。多分定番ノードがあると思うので探してみたいと思います。
コメント