Technology

C# Entity Framework Career Development IT

c entity framework career development it
C# Entity Framework Career Development IT | SiamCafe Blog
2025-07-20· อ. บอม — SiamCafe.net· 11,476 คำ

EF Core

C# Entity Framework Core ORM DbContext Migration LINQ Repository Pattern Clean Architecture Performance SQL Server PostgreSQL Career Development

FeatureEF CoreDapperADO.NETNHibernate
TypeFull ORMMicro ORMRaw ADOFull ORM
Performanceดีดีมากดีที่สุดปานกลาง
Productivityสูงมากสูงต่ำสูง
MigrationBuilt-inไม่มีไม่มีFluentMigrator
LINQFull supportไม่มีไม่มีPartial
Learningปานกลางง่ายง่ายสูง
เหมาะกับMost projectsHigh perf queryLegacy/controlComplex domain

DbContext and Models

# === EF Core DbContext Configuration ===

# // Models/Product.cs
# public class Product
# {
#     public int Id { get; set; }
#     public string Name { get; set; } = string.Empty;
#     public decimal Price { get; set; }
#     public int CategoryId { get; set; }
#     public Category Category { get; set; } = null!;
#     public ICollection<OrderItem> OrderItems { get; set; } = new List<OrderItem>();
#     public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
#     public bool IsActive { get; set; } = true;
# }
#
# // Models/Category.cs
# public class Category
# {
#     public int Id { get; set; }
#     public string Name { get; set; } = string.Empty;
#     public ICollection<Product> Products { get; set; } = new List<Product>();
# }
#
# // Data/AppDbContext.cs
# public class AppDbContext : DbContext
# {
#     public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
#
#     public DbSet<Product> Products => Set<Product>();
#     public DbSet<Category> Categories => Set<Category>();
#     public DbSet<Order> Orders => Set<Order>();
#
#     protected override void OnModelCreating(ModelBuilder modelBuilder)
#     {
#         modelBuilder.Entity<Product>(entity =>
#         {
#             entity.HasIndex(e => e.Name);
#             entity.Property(e => e.Price).HasPrecision(18, 2);
#             entity.HasOne(e => e.Category)
#                   .WithMany(c => c.Products)
#                   .HasForeignKey(e => e.CategoryId);
#         });
#     }
# }

from dataclasses import dataclass

@dataclass
class EFCommand:
    command: str
    description: str
    example: str

commands = [
    EFCommand("dotnet ef migrations add", "สร้าง Migration ใหม่", "dotnet ef migrations add AddProductTable"),
    EFCommand("dotnet ef database update", "Apply Migration ล่าสุด", "dotnet ef database update"),
    EFCommand("dotnet ef migrations remove", "ลบ Migration ล่าสุด", "dotnet ef migrations remove"),
    EFCommand("dotnet ef migrations list", "แสดง Migration ทั้งหมด", "dotnet ef migrations list"),
    EFCommand("dotnet ef migrations script", "สร้าง SQL Script", "dotnet ef migrations script -o migration.sql"),
    EFCommand("dotnet ef database drop", "ลบ Database", "dotnet ef database drop --force"),
    EFCommand("dotnet ef dbcontext scaffold", "Scaffold จาก DB", 'dotnet ef dbcontext scaffold "ConnStr" Npgsql.EntityFrameworkCore.PostgreSQL'),
]

print("=== EF Core CLI Commands ===")
for c in commands:
    print(f"  [{c.command}]")
    print(f"    {c.description}")
    print(f"    Example: {c.example}")

LINQ Queries and Performance

# === LINQ Query Patterns ===

# // Basic Query
# var products = await _context.Products
#     .Where(p => p.IsActive && p.Price > 100)
#     .OrderByDescending(p => p.CreatedAt)
#     .Take(10)
#     .ToListAsync();
#
# // Eager Loading (fix N+1)
# var productsWithCategory = await _context.Products
#     .Include(p => p.Category)
#     .Where(p => p.IsActive)
#     .ToListAsync();
#
# // Projection (select only needed fields)
# var productDtos = await _context.Products
#     .Where(p => p.IsActive)
#     .Select(p => new ProductDto
#     {
#         Id = p.Id,
#         Name = p.Name,
#         Price = p.Price,
#         CategoryName = p.Category.Name
#     })
#     .ToListAsync();
#
# // AsNoTracking (read-only performance)
# var readOnlyProducts = await _context.Products
#     .AsNoTracking()
#     .Where(p => p.CategoryId == categoryId)
#     .ToListAsync();
#
# // Compiled Query (frequently called)
# private static readonly Func<AppDbContext, int, Task<Product?>> GetProductById =
#     EF.CompileAsyncQuery((AppDbContext ctx, int id) =>
#         ctx.Products.FirstOrDefault(p => p.Id == id));

@dataclass
class PerfTip:
    problem: str
    solution: str
    impact: str
    code_change: str

tips = [
    PerfTip("N+1 Query", "Use Include() for Eager Loading", "10x faster for related data",
        ".Include(p => p.Category)"),
    PerfTip("Tracking overhead", "Use AsNoTracking() for reads", "2-3x faster read queries",
        ".AsNoTracking()"),
    PerfTip("Over-fetching", "Use Select() Projection", "Reduce data transfer 50-80%",
        ".Select(p => new { p.Id, p.Name })"),
    PerfTip("Repeated queries", "Use Compiled Query", "Eliminate query compilation cost",
        "EF.CompileAsyncQuery(...)"),
    PerfTip("Slow inserts", "Use AddRange() + batch", "10-100x faster bulk insert",
        "_context.Products.AddRange(list)"),
    PerfTip("Missing index", "Add HasIndex in OnModelCreating", "100x faster filtered queries",
        "entity.HasIndex(e => e.Name)"),
    PerfTip("Complex query", "Use Raw SQL via FromSqlRaw", "Optimal for complex joins/CTEs",
        '_context.Products.FromSqlRaw("SELECT ...")'),
]

print("\n=== Performance Tips ===")
for t in tips:
    print(f"  [{t.problem}] → {t.solution}")
    print(f"    Impact: {t.impact}")
    print(f"    Code: {t.code_change}")

Repository Pattern

# === Repository Pattern with EF Core ===

# // IRepository.cs
# public interface IRepository<T> where T : class
# {
#     Task<T?> GetByIdAsync(int id);
#     Task<IEnumerable<T>> GetAllAsync();
#     Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate);
#     Task AddAsync(T entity);
#     void Update(T entity);
#     void Remove(T entity);
# }
#
# // Repository.cs
# public class Repository<T> : IRepository<T> where T : class
# {
#     protected readonly AppDbContext _context;
#     protected readonly DbSet<T> _dbSet;
#
#     public Repository(AppDbContext context)
#     {
#         _context = context;
#         _dbSet = context.Set<T>();
#     }
#
#     public async Task<T?> GetByIdAsync(int id) => await _dbSet.FindAsync(id);
#     public async Task<IEnumerable<T>> GetAllAsync() => await _dbSet.ToListAsync();
#     public async Task AddAsync(T entity) => await _dbSet.AddAsync(entity);
#     public void Update(T entity) => _dbSet.Update(entity);
#     public void Remove(T entity) => _dbSet.Remove(entity);
# }
#
# // IUnitOfWork.cs
# public interface IUnitOfWork : IDisposable
# {
#     IRepository<Product> Products { get; }
#     IRepository<Category> Categories { get; }
#     Task<int> SaveChangesAsync();
# }

@dataclass
class CareerLevel:
    level: str
    ef_skills: str
    salary_range: str
    project_type: str

levels = [
    CareerLevel("Junior .NET Dev", "Basic CRUD, Migration, LINQ basics",
        "25-45K THB", "Simple CRUD apps, internal tools"),
    CareerLevel("Mid .NET Dev", "Repository Pattern, Performance tuning, Complex LINQ",
        "45-80K THB", "Web API, microservices, e-commerce"),
    CareerLevel("Senior .NET Dev", "Clean Architecture, CQRS, Advanced EF, Raw SQL",
        "80-150K THB", "Enterprise apps, system design"),
    CareerLevel(".NET Architect", "Multi-DB strategy, Sharding, Event Sourcing",
        "120-200K+ THB", "Platform design, team leadership"),
]

print("Career Path (.NET + EF Core):")
for l in levels:
    print(f"  [{l.level}] Salary: {l.salary_range}")
    print(f"    EF Skills: {l.ef_skills}")
    print(f"    Projects: {l.project_type}")

เคล็ดลับ

Entity Framework Core คืออะไร

ORM .NET C# Class Database SQL Server PostgreSQL MySQL Code-First Database-First Migration LINQ Query Schema Change

ช่วยพัฒนาอาชีพ IT อย่างไร

.NET Developer ทุกตำแหน่ง ASP.NET Core Blazor MAUI Resume Repository Unit of Work CQRS Performance Portfolio Clean Architecture

Migration ทำอย่างไร

dotnet ef migrations add update remove list script SQL CI/CD Pipeline Production Rollback Schema Change

ปรับ Performance อย่างไร

N+1 Include Eager Loading AsNoTracking Read-only Select Projection Compiled Query Batch Insert Index Raw SQL Logging Generated SQL

สรุป

C# Entity Framework Core ORM DbContext Migration LINQ Repository Pattern Performance AsNoTracking Include Clean Architecture Career Development Production

📖 บทความที่เกี่ยวข้อง

JavaScript Deno Deploy Career Development ITอ่านบทความ → C# Entity Framework IoT Gatewayอ่านบทความ → C# Entity Framework Testing Strategy QAอ่านบทความ → C# Entity Framework CQRS Event Sourcingอ่านบทความ → C# Entity Framework Clean Architectureอ่านบทความ →

📚 ดูบทความทั้งหมด →