C# Entity Framework Agile Scrum Kanban
C# Entity Framework Agile Scrum Kanban คืออะไร
Entity Framework (EF Core) เป็น ORM (Object-Relational Mapper) สำหรับ .NET ที่ช่วยให้ทำงานกับฐานข้อมูลผ่าน C# objects โดยไม่ต้องเขียน SQL ตรงๆ Agile เป็นแนวคิดการพัฒนาซอฟต์แวร์ที่เน้น iterations สั้นๆ Scrum และ Kanban เป็น frameworks ยอดนิยมภายใต้ Agile บทความนี้รวมการใช้ EF Core ในโปรเจกต์ที่บริหารด้วย Scrum/Kanban รวมถึง database migrations ใน sprint cycles, Kanban board สำหรับ data model changes และ best practices สำหรับทีม agile
EF Core พื้นฐาน
# efcore_basics.py — EF Core concepts (Python equivalent demo) import json class EFCoreBasics: CONCEPTS = { "dbcontext": { "name": "DbContext", "description": "Entry point สำหรับทำงานกับ database (Unit of Work pattern)", "csharp": "public class AppDbContext : DbContext { public DbSet Users { get; set; } }", }, "dbset": { "name": "DbSet", "description": "Collection ของ entities ที่ map กับ database table", "csharp": "DbSetScrum สำหรับ EF Core Projects
# scrum_ef.py — Scrum workflow with EF Core import json import random class ScrumEFCore: SPRINT_WORKFLOW = { "planning": { "phase": "Sprint Planning", "ef_tasks": [ "Review pending migration requests", "Estimate data model changes (story points)", "Plan database migration order (dependencies)", "Assign EF Core tasks to developers", ], }, "development": { "phase": "Sprint Development (2 weeks)", "ef_tasks": [ "Create feature branch for data model changes", "Add EF Core migration: dotnet ef migrations add ", "Write LINQ queries for new features", "Unit test with InMemoryDatabase provider", "Integration test with test database", ], }, "review": { "phase": "Sprint Review", "ef_tasks": [ "Demo new database features", "Review migration scripts (peer review)", "Check query performance (SQL profiling)", "Validate data integrity", ], }, "deployment": { "phase": "Sprint Deployment", "ef_tasks": [ "Apply migrations to staging: dotnet ef database update", "Run integration tests on staging", "Apply migrations to production (with rollback plan)", "Monitor database performance post-deploy", ], }, } STORY_EXAMPLES = [ {"id": "US-101", "story": "As a user, I can update my profile", "ef_task": "Add ProfileImage column to Users table", "points": 3}, {"id": "US-102", "story": "As an admin, I can view order analytics", "ef_task": "Create OrderAnalytics view + LINQ query", "points": 5}, {"id": "US-103", "story": "As a user, I can save favorite products", "ef_task": "Create Favorites junction table + navigation properties", "points": 5}, {"id": "US-104", "story": "As a system, soft-delete instead of hard-delete", "ef_task": "Add IsDeleted column + global query filter", "points": 8}, ] def show_workflow(self): print("=== Scrum + EF Core Workflow ===\n") for key, phase in self.SPRINT_WORKFLOW.items(): print(f"[{phase['phase']}]") for task in phase["ef_tasks"][:3]: print(f" • {task}") print() def show_stories(self): print("=== User Stories with EF Tasks ===") for story in self.STORY_EXAMPLES: print(f" [{story['id']}] ({story['points']}pts) {story['story']}") print(f" EF: {story['ef_task']}") scrum = ScrumEFCore() scrum.show_workflow() scrum.show_stories()Kanban Board สำหรับ Database Changes
# kanban_ef.py — Kanban board for EF Core
import json
import random
class KanbanEFCore:
COLUMNS = {
"backlog": {
"name": "Backlog",
"wip_limit": None,
"items": [
{"task": "Add audit log table", "type": "Migration", "priority": "Medium"},
{"task": "Optimize N+1 query in OrderService", "type": "Performance", "priority": "High"},
{"task": "Add full-text search index", "type": "Migration", "priority": "Low"},
],
},
"analysis": {
"name": "Analysis / Design",
"wip_limit": 2,
"items": [
{"task": "Design multi-tenant schema", "type": "Architecture", "priority": "High"},
],
},
"development": {
"name": "In Development",
"wip_limit": 3,
"items": [
{"task": "Add SoftDelete global filter", "type": "Migration", "priority": "High"},
{"task": "Implement repository pattern", "type": "Refactor", "priority": "Medium"},
],
},
"review": {
"name": "Code Review",
"wip_limit": 2,
"items": [
{"task": "Migration: Add UserPreferences table", "type": "Migration", "priority": "Medium"},
],
},
"testing": {
"name": "Testing",
"wip_limit": 2,
"items": [],
},
"done": {
"name": "Done",
"wip_limit": None,
"items": [
{"task": "Add index on Orders.CreatedAt", "type": "Performance", "priority": "High"},
],
},
}
def show_board(self):
print("=== Kanban Board — EF Core Tasks ===\n")
for key, col in self.COLUMNS.items():
wip = f" (WIP: {col['wip_limit']})" if col["wip_limit"] else ""
count = len(col["items"])
print(f"[{col['name']}{wip}] — {count} items")
for item in col["items"][:2]:
print(f" • [{item['priority']}] {item['task']} ({item['type']})")
print()
def metrics(self):
print("=== Kanban Metrics ===")
metrics = {
"Lead Time (avg)": f"{random.randint(3, 10)} days",
"Cycle Time (avg)": f"{random.randint(1, 5)} days",
"Throughput": f"{random.randint(5, 15)} items/week",
"WIP": f"{random.randint(3, 8)} items",
"Blocked": f"{random.randint(0, 2)} items",
}
for m, v in metrics.items():
print(f" {m}: {v}")
kanban = KanbanEFCore()
kanban.show_board()
kanban.metrics()
Migration Management
# migrations.py — EF Core migration management import json class MigrationManagement: COMMANDS = { "add": "dotnet ef migrations add AddUserPreferences", "update": "dotnet ef database update", "rollback": "dotnet ef database update PreviousMigrationName", "remove": "dotnet ef migrations remove", "script": "dotnet ef migrations script --idempotent -o migration.sql", "list": "dotnet ef migrations list", "bundle": "dotnet ef migrations bundle -o efbundle", } BEST_PRACTICES = { "naming": { "name": "Migration Naming Convention", "convention": "YYYYMMDD_Description (เช่น 20250115_AddUserPreferences)", "bad": "Migration1, Update2, Fix3", }, "small_migrations": { "name": "Small, Focused Migrations", "do": "1 migration = 1 logical change (add table, add column)", "dont": "1 migration = 10 different changes (hard to rollback)", }, "data_migrations": { "name": "Data Migrations แยกจาก Schema Migrations", "do": "Schema migration ก่อน → Data migration แยก → Cleanup migration", "dont": "รวม schema + data + cleanup ใน migration เดียว", }, "review": { "name": "Review Generated SQL", "do": "dotnet ef migrations script → review SQL ก่อน apply production", "dont": "Apply migrations โดยไม่ดู generated SQL", }, } CSHARP_MIGRATION = """ // Migrations/20250115_AddUserPreferences.cs public partial class AddUserPreferences : Migration { protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable( name: "UserPreferences", columns: table => new { Id = table.ColumnTesting & Performance
# testing.py — EF Core testing in agile import json import random class EFCoreTesting: TESTING_TYPES = { "unit": { "name": "Unit Tests (InMemory)", "provider": "Microsoft.EntityFrameworkCore.InMemory", "speed": "เร็วมาก", "accuracy": "ปานกลาง (ไม่ test SQL generation)", }, "integration": { "name": "Integration Tests (Real DB)", "provider": "Testcontainers (Docker)", "speed": "ปานกลาง", "accuracy": "สูง (test จริงกับ database)", }, "performance": { "name": "Performance Tests", "provider": "BenchmarkDotNet + SQL Profiler", "speed": "ช้า", "accuracy": "สูงมาก", }, } CSHARP_TEST = """ // Tests/UserServiceTests.cs [Fact] public async Task CreateUser_ShouldAddToDatabase() { // Arrange var options = new DbContextOptionsBuilderFAQ - คำถามที่พบบ่อย
Q: Scrum กับ Kanban อันไหนดีสำหรับ EF Core projects?
A: Scrum: ดีสำหรับ greenfield projects ที่ต้อง plan migrations ล่วงหน้า Kanban: ดีสำหรับ maintenance, bug fixes, continuous delivery ทีมใหญ่: Scrum (structure ชัดเจน) ทีมเล็ก: Kanban (flexible กว่า) หลายทีมใช้ Scrumban (ผสม Scrum ceremonies + Kanban board)
Q: Migration conflicts ใน team แก้ยังไง?
A: ป้องกัน: 1 migration ต่อ 1 feature branch, merge ก่อน create migration แก้ไข: dotnet ef migrations remove → resolve conflicts → สร้าง migration ใหม่ Rule: ห้าม edit migration ที่ apply แล้ว (สร้าง migration ใหม่แทน) ใช้ Kanban WIP limit: จำกัด migration tasks ที่ทำพร้อมกัน
Q: EF Core กับ Dapper อันไหนดี?
A: EF Core: productivity สูง, migrations, LINQ, complex relationships Dapper: performance สูงกว่า, control SQL ได้เต็มที่, lightweight ใช้ EF Core: CRUD operations, complex domain, rapid development ใช้ Dapper: read-heavy, performance critical, reporting queries หลายทีมใช้ทั้งคู่: EF Core สำหรับ writes, Dapper สำหรับ complex reads
Q: Production migration ทำอย่างไรให้ปลอดภัย?
A: 1. Generate SQL script: dotnet ef migrations script --idempotent 2. Review SQL ด้วย DBA หรือ senior dev 3. Test บน staging ที่ clone จาก production 4. Backup production database 5. Apply ใน maintenance window 6. มี rollback plan (Down migration) 7. Monitor หลัง apply (errors, performance)