Migrations and seeding data with Entity Framework 101
สวัสดีครับท่านผู้อ่าน วันนี้ก็อยากจะมาแชร์แนวทางการใช้ Entity Framework ในการ Migrations และ Seeding data ครับในตัวอย่างจะเป็นตัวอย่างง่ายๆเพื่อเป็นแนวทางให้ผู้ที่สนใจและไม่รู้จะเริ่มยังไงให้สามารถทำได้เบื้องต้นครับ
โปรดอ่านก่อนไปต่อ: ในตัวอย่างนี้จะใช้งาน Fluent APIs ในการสร้าง Model และผมใช้ .Net Core SDK version 2.2.110 ในตัวอย่างนะครับ
สร้าง ConnectionString ที่ไฟล์ appsettings.Development.json
Server = ที่อยู่ของ database server ของท่าน
Database = ตั้งชื่ออะไรก็ได้นะเพราะถ้าไม่มีระบบจะไปสร้างให้เองUser Id = sa(เป็น default) จริงๆก็ควรจะเปลี่ยนเป็น account อื่นและจัดการ Permission นะครับ
Password = Password ที่เอาไว้ Access Database ของท่าน
ติดตั้ง Package ที่จำเป็นสำหรับการทำ Migrations กับ SQL Server
ในตัวอย่างใช้ Microsoft.EntityFrameworkCore.SqlServer version 2.2.2
โปรดอ่าน: กรณีใช้ .Net Core SDK 3.x.x ให้ท่านใช้ version ที่ match กับ SDK ของท่าน
ในตัวอย่างใช้ Microsoft.EntityFrameworkCore.Design version 2.2.6
โปรดอ่าน: กรณีใช้ .Net Core SDK 3.x.x ให้ท่านใช้ version ที่ match กับ SDK ของท่าน
สร้าง Model สำหรับทำ Migrations
ในตัวอย่างนี้ผมใช้วิธี Separate Configuration Classes เพื่อให้ไฟล์ Context ของเราดู Clean
MainModel.cs
Order.cs
OrderConfiguration.cs
build.Property(i => i.CreatedDateTime) = คือการใช้เข้าถึง property ที่ต้องการ
IsRequired() = บอกว่า Column นี้จะ NOT NULL(Column ใน table)
HasMaxLength(200) = กำหนดจำนวนความยาวที่ Column จะรองรับได้
HasDefaultValueSql = กำหนดค่าตั้งต้นให้ Column "CreatedDateTime" โดยใช้ function GETUTCDATE() ของ SQL Server
HasMany/WithOne = จะต้องใช้คู่กันเสมอ ในตัวอย่างเป็นการทำ one-to-many relational ของ table: Order กับ table: item โดยที่ table: item จะเก็บ Foreign key คือ OrderId ไว้ที่ table: item
OnDelete = กำหนดว่าหากเราทำการลบ Order ให้ระบบ set value เป็น NULL สำหรับ item ที่เท่ากับ OrderId ที่โดนลบ*OnDelete มีให้ใช้ เช่น Restrict, SetNull และ Cascade* HasMaxLength จะใช้ได้กับ Property type string เพราะ Property type string หลังจากทำการสร้าง table แล้วจะได้ Data type nvarchar หากเราไม่กำหนด HasMaxLength ระบบใช้ nvarchar(max) ให้เราอัตโนมัติ
Item.cs
ItemConfiguration.cs
จากตัวอย่างด้านบนผมใช้งาน Fluent APIs แบบ Chained call คือการเรียกใช้งาน method ของ Fluent APIs ไปเรื่อยๆตามภาพด้านบน(OrderConfiguration.cs และ ItemConfiguration.cs) สำหรับตัวอย่าง method ด้านบนรายละเอียดตามล่างนี้ครับ
build.Property(i => i.Name) = คือการใช้เข้าถึง property ที่ต้องการ
IsRequired() = บอกว่า Column นี้จะ NOT NULL(Column ใน table)
HasMaxLength(200) = กำหนดจำนวนความยาวที่ Column จะรองรับได้
HasDefaultValueSql = กำหนดค่าตั้งต้นให้ Column "CreatedDateTime" โดยใช้ function GETUTCDATE() ของ SQL Server * HasMaxLength จะใช้ได้กับ Property type string เพราะ Property type string หลังจากทำการสร้าง table แล้วจะได้ Data type nvarchar หากเราไม่กำหนด HasMaxLength ระบบใช้ nvarchar(max) ให้เราอัตโนมัติ
สร้างไฟล์ ModelBuilderExtensions.cs สำหรับเก็บ data ที่จะทำการ Seed
ในตัวอย่างเป็นการสร้าง ไฟล์ Extension จาก ModelBuilder
สร้างไฟล์ AppDbContext.cs
OnModelCreating = จะเรียกเมื่อมีการสร้าง context ครั้งจาก .Net CoreApplyConfigurationsFromAssembly = เป็น method ที่เข้ามา .Net Core 2.2.x ขึ้นไปสำหรับ method นี้จะทำการไปหาไฟล์ที่ Implement มาจาก IEntityTypeConfiguration(ไฟล์ที่เราใช้ในการ Configure Fluent APIs)ในตัวอย่างจะมี 2 ไฟล์คือ OrderConfiguration.cs และ ItemConfiguration.cs
Seed() method = method ที่เราจะสร้างขึ้นมาเพื่อ seeding data to table ที่ต้องการ
สร้าง Migrations ไฟล์
dotnet ef migrations add <Your-Migrations-name>
หลังจากทำการสร้างเสร็จและไม่มี Errors จะได้ Migrations Folder ตามภาพ
โปรดอ่าน: สำหรับ Migrations ไฟล์ของท่านจะมากจะน้อยก็ขึ้นอยู่กับจำนวนครั้งที่ทำการ add migrations ของท่าน
ทดสอบสร้าง database, table และทำการ seeding data ด้วยคำสั่ง
dotnet ef migrations database update
เนื่องจากผมได้ทำการ Migrations ไปก่อนหน้านี้และไม่มีการเปลี่ยนแปลงระบบจึงแจ้งว่า
หากไม่มี Errors ให้ท่านดูผลลัพธ์ที่ database ก็จะได้ผลลัพธ์ประมาณนี้ ตามภาพด้านล่าง
ก็จบกันไปแล้วครับสำหรับการทำ Migrations และ Seeding data ด้วย Entity Framework Core ก็หวังว่าจะนำไปต่อยอดกับ Project ของท่านได้นะครับ Enjoy coding บายยยยย :=)