ู‚ูˆู„ู†ุง ู‚ุจู„ ูƒุฏุง ุงู†ู†ุง ู…ู…ูƒู† ู†ุนู…ู„ Mapping ู…ู† ุงู„ู€ Database ู„ู„ูƒูˆุฏ ูˆุงู„ุนูƒุณุŒ ูˆุฏุง ุจูŠุนุชู…ุฏ ุงู†ุช ุดุบุงู„ Code-first or Database-First.

ู‡ู†ุฑูƒุฒ ุนู„ู‰ ุทุฑูŠู‚ุฉ ุงู„ู€ Code-First. ุงู„ุทุฑูŠู‚ุฉ ุฏูŠ ู…ุนู†ุงู‡ุง ุฅู†ู†ุง ุจู†ุจุฏุฃ ุจูƒุชุงุจุฉ ุงู„ู€ Classes ุจุชุงุนุชู†ุง ุจู„ุบุฉ C# ุงู„ุฃูˆู„ุŒ ูˆุจุนุฏูŠู† ุจู†ุนุชู…ุฏ ุนู„ู‰ ุงู„ู€ Entity Framework Core ุฅู†ู‡ ู‡ูˆ ุงู„ู„ูŠ ูŠุจู†ูŠ ุฃูˆ ูŠุนุฏู„ ุงู„ู€ Database ุจู†ุงุกู‹ ุนู„ู‰ ุงู„ู€ Classes ุฏูŠ.

ุงู„ู€ Models (ุฃูˆ ุงู„ู€ Entities)

ู‚ุจู„ ุฃูŠ ุญุงุฌุฉ ููŠ ุงู„ู€ Code-FirstุŒ ู„ุงุฒู… ู†ุฌู‡ุฒ ุงู„ู€ Models ุจุชุงุนุชู†ุง. ุฏูŠ ู‡ูŠ ุงู„ู€ Classes ุงู„ู„ูŠ ุจุชู…ุซู„ ุงู„ุฏุงุชุง ุงู„ุฃุณุงุณูŠุฉ ุงู„ู„ูŠ ุงู„ุฃุจู„ูƒูŠุดู† ุจูŠุชุนุงู…ู„ ู…ุนุงู‡ุง.

  • ุชู†ุธูŠู… ุงู„ุดุบู„: ุนุดุงู† ุงู„ูƒูˆุฏ ูŠุจู‚ู‰ ู…ู†ุธู…ุŒ ุจู†ุนู…ู„ folder ู…ุฎุตูˆุต ููŠ ุงู„ู€ project ูˆู†ุญุท ุฌูˆุงู‡ ุงู„ู€ Classes ุฏูŠ. ู…ู…ูƒู† ู†ุณู…ูŠ ุงู„ู€ folder ุฏู‡ Models ุฃูˆ Entities ุฃูˆ Domain.
  • ุงู„ุฃุณู…ุงุก ุงู„ู…ุฎุชู„ูุฉ: ุงู„ู€ Classes ุฏูŠ ู„ูŠู‡ุง ูƒุฐุง ุงุณู… ู…ู…ูƒู† ุชุณู…ุนู‡ู…:
    • ุงู„ู€ Entities: ู„ุฃู†ู‡ุง ุจุชู…ุซู„ ุงู„ูƒูŠุงู†ุงุช ุฃูˆ ุงู„ุฃุดูŠุงุก ุงู„ุฃุณุงุณูŠุฉ ููŠ ุงู„ุณูŠุณุชู… ุจุชุงุนูƒ (ุฒูŠ ู…ูˆุธูุŒ ู…ู†ุชุฌุŒ ู‚ุณู…ุŒ ูุงุชูˆุฑุฉ).
    • ุงู„ู€ POCO Class: ูˆุฏูŠ ุงุชูƒู„ู…ู†ุง ุนู†ู‡ุง ุจุงู„ุชูุตูŠู„ุŒ ูˆู‡ูŠ ุงุฎุชุตุงุฑ ู„ู€ โ€œPlain Old CLR Objectโ€. ุงู„ููƒุฑุฉ ุฅู†ู‡ุง ุจุชุจู‚ู‰ Classes ุจุณูŠุทุฉ ุฌุฏู‹ุงุŒ ุจุชุฑูƒุฒ ุนู„ู‰ ุฅู†ู‡ุง ุชุดูŠู„ data ููŠ ุงู„ู€ properties ุจุชุงุนุชู‡ุงุŒ ูˆู…ููŠู‡ุงุด logic ูƒุชูŠุฑ ุฃูˆ ุงุนุชู…ุงุฏูŠุฉ ุนู„ู‰ framework ู…ุนูŠู†.
    • ุงู„ู€ Domain Models: ู„ุฃู†ู‡ุง ุจุชู…ุซู„ ุงู„ู…ูุงู‡ูŠู… ุงู„ุฃุณุงุณูŠุฉ ููŠ ู…ุฌุงู„ ุงู„ุดุบู„ (ุงู„ู€ Domain) ุจุชุงุน ุงู„ุฃุจู„ูƒูŠุดู†.

ู…ุซุงู„ ุนู…ู„ูŠ: ุงู„ู€ Employee Class

ุชุนุงู„ู‰ ู†ุนู…ู„ Class ุจุณูŠุท ูƒู…ุซุงู„ุŒ ูˆู‡ู†ุณู…ูŠู‡ Employee (ู…ูˆุธู):

// File: Models/Employee.cs
internal class Employee
{
    // Property for Employee ID
    public int Id { get; set; }
 
    // Property for Employee Name
    public string Name { get; set; }
 
    // Property for Employee Salary
    public double Salary { get; set; }
 
    // Property for Employee Age (Nullable)
    public int? Age { get; set; }
}
  • ุฒูŠ ู…ุง ุฅู†ุช ุดุงูŠูุŒ ุงู„ู€ Class ุฏู‡ ู…ุซุงู„ ูƒูˆูŠุณ ุฌุฏู‹ุง ุนู„ู‰ ุงู„ู€ POCO Class. ู…ุฌุฑุฏ properties ุจุณูŠุทุฉ ุจุชุณุชุฎุฏู… ุงู„ู€ auto-implemented properties ({get; set;}) ุนุดุงู† ุชุดูŠู„ ุงู„ุฏุงุชุง.

ุงู„ู€ Mapping (ุงู„ุชุญูˆูŠู„ ู…ู† ูƒูˆุฏ ู„ุฏุงุชุงุจูŠุฒ)

ุฏู„ูˆู‚ุชูŠ ุฅุญู†ุง ุนู…ู„ู†ุง ุงู„ู€ Employee Class. ุงู„ุณุคุงู„ ุงู„ู…ู‡ู…: ุฅุฒุงูŠ ุงู„ู€ EF Core ู‡ูŠุนุฑู ูŠุญูˆู„ ุงู„ู€ Class ุฏู‡ ู„ุญุงุฌุฉ ูŠูู‡ู…ู‡ุง ุฌูˆู‡ ุงู„ู€ DatabaseุŸ (ุฒูŠ ุฅู†ู‡ ูŠุนู…ู„ Table ุจุงู„ู€ Columns ุงู„ู…ู†ุงุณุจุฉ). ุงู„ุนู…ู„ูŠุฉ ุฏูŠ ุจู†ุณู…ูŠู‡ุง Mapping.

ุงู„ู€ EF Core ุจูŠุฏูŠู†ุง ูƒุฐุง ุทุฑูŠู‚ุฉ ู†ุนู…ู„ ุจูŠู‡ุง ุงู„ู€ Mapping ุฏู‡. ููŠู‡ ุฃุฑุจุน ุทุฑู‚ ุฃุณุงุณูŠุฉุŒ ูˆุงู„ู…ู‡ู… ู†ุนุฑู ุฅู† ุงู„ุทุฑู‚ ุฏูŠ ุจุชูƒู…ู„ ุจุนุถู‡ุง. ูŠุนู†ูŠ ุฅูŠู‡ุŸ ูŠุนู†ูŠ ุงู„ู€ EF Core ุจูŠุจุฏุฃ ุจุงู„ุทุฑูŠู‚ุฉ ุงู„ุฃุณู‡ู„ ูˆุงู„ุฃูƒุซุฑ ุดูŠูˆุนู‹ุง (ุฑู‚ู… 1)ุŒ ูˆู„ูˆ ุฅู†ุช ู…ุญุชุงุฌ ุชุชุญูƒู… ุฃูƒุชุฑ ุฃูˆ ุชุบูŠุฑ ุญุงุฌุฉ ููŠ ุงู„ุณู„ูˆูƒ ุงู„ุงูุชุฑุงุถูŠ ุฏู‡ุŒ ุจุชุจุฏุฃ ุชุณุชุฎุฏู… ุงู„ุทุฑู‚ ุงู„ู„ูŠ ุจุนุฏู‡ุง (2ุŒ 3ุŒ 4) ุนุดุงู† ุชุนู…ู„ ุชุฎุตูŠุต ุฒูŠุงุฏุฉ.

1. By Convention (Default)

ูƒู„ู…ุฉ Convention ู‡ู†ุง ู…ุนู†ุงู‡ุง โ€œุงู„ุนูุฑูโ€ ุฃูˆ โ€œุงู„ุงุชูุงู‚ ุงู„ุถู…ู†ูŠโ€ ุฃูˆ โ€œุงู„ุณู„ูˆูƒ ุงู„ุงูุชุฑุงุถูŠโ€.

  • ุงู„ููƒุฑุฉ ุงู„ุฃุณุงุณูŠุฉ: ุฏูŠ ุงู„ุทุฑูŠู‚ุฉ ุงู„ู„ูŠ ุงู„ู€ EF Core ุจูŠุดุชุบู„ ุจูŠู‡ุง ู„ูˆุญุฏู‡ ู…ู† ุบูŠุฑ ู…ุง ุฅู†ุช ุชูƒุชุจ ุฃูŠ ูƒูˆุฏ ู…ุฎุตูˆุต ู„ู„ู€ Mapping. ู‡ูˆ ุนู†ุฏู‡ ู…ุฌู…ูˆุนุฉ ู‚ูˆุงุนุฏ (ุฒูŠ ุงุชูุงู‚ ุจูŠู†ูƒ ูˆุจูŠู†ู‡) ุจูŠู…ุดูŠ ุนู„ูŠู‡ุง ุนุดุงู† ูŠูู‡ู… ุงู„ู€ Classes ุจุชุงุนุชูƒ ูˆูŠุญูˆู„ู‡ุง ู„ู€ Database Schema ููŠ ุงู„ุฏุงุชุงุจูŠุฒ.
  • ู…ูŠู† ุงู„ู„ูŠ ุจูŠุญุฏุฏู‡ุงุŸ ุงู„ู€ Conventions ุฏูŠ ุฌุงูŠุฉ ู…ุน ุงู„ู€ EF Core ู†ูุณู‡. ุฅู†ุช ูƒู€ developer ู…ุฌุฑุฏ ุจุชูƒุชุจ ุงู„ูƒูˆุฏ ุจุชุงุนูƒ ุจุทุฑูŠู‚ุฉ ู‚ูŠุงุณูŠุฉ (ุฒูŠ ุชุณู…ูŠุฉ ุงู„ู€ Primary Key ุจู€ Id)ุŒ ูˆู‡ูˆ ุจูŠูู‡ู… ู‚ุตุฏูƒ.
  • ุงู„ู…ุฌู‡ูˆุฏ ุงู„ู…ุทู„ูˆุจ: ุชู‚ุฑูŠุจู‹ุง ู…ููŠุด! ุฏูŠ ุงู„ุทุฑูŠู‚ุฉ ุงู„ุทุจูŠุนูŠุฉ ูˆุงู„ุงูุชุฑุงุถูŠุฉุŒ ู…ุด ู…ุญุชุงุฌ ุชุนู…ู„ ุฃูŠ ุญุงุฌุฉ ุฒูŠุงุฏุฉ ููŠ ุฃุบู„ุจ ุงู„ุญุงู„ุงุช ุงู„ุจุณูŠุทุฉ.

ุฃู…ุซู„ุฉ ุนู„ู‰ ุงู„ู€ Conventions ุงู„ู…ุดู‡ูˆุฑุฉ:

  • ุชุญุฏูŠุฏ ุงู„ู€ Primary Key (ุงู„ู…ูุชุงุญ ุงู„ุฃุณุงุณูŠ):
    • ู„ูˆ ุนู†ุฏูƒ property ููŠ ุงู„ู€ Class ุงุณู…ู‡ุง Id (ุฒูŠ ููŠ ู…ุซุงู„ู†ุง).
    • ุฃูˆ ู„ูˆ ุงุณู…ู‡ุง ู†ูุณ ุงุณู… ุงู„ู€ Class + Id (ูŠุนู†ูŠ ู„ูˆ ุงู„ูƒู„ุงุณ ุงุณู…ู‡ EmployeeุŒ ูˆุงู„ู€ property ุงุณู…ู‡ุง EmployeeId).
    • ููŠ ุงู„ุญุงู„ุชูŠู† ุฏูˆู„ุŒ ุงู„ู€ EF Core ู„ูˆุญุฏู‡ (By Convention) ู‡ูŠูุชุฑุถ ุฅู† ุงู„ู€ property ุฏูŠ ู‡ูŠ ุงู„ู€ Primary Key ุจุชุงุน ุงู„ู€ Table ุงู„ู„ูŠ ู‡ูŠุชุนู…ู„.
    • ูˆูƒู…ุงู†: ููŠ ุฃุบู„ุจ ุฃู†ูˆุงุน ุงู„ุฏุงุชุงุจูŠุฒ (ุฒูŠ SQL Server)ุŒ ู‡ูŠุฎู„ูŠ ุงู„ู€ Primary Key ุฏู‡ ู…ู† ุงู„ู†ูˆุน IdentityุŒ ูŠุนู†ูŠ ู‚ูŠู…ุชู‡ ู‡ุชุฒูŠุฏ ุชู„ู‚ุงุฆูŠู‹ุง ู…ุน ูƒู„ record ุฌุฏูŠุฏ (Auto-increment).
  • ุชุญูˆูŠู„ ุฃู†ูˆุงุน ุงู„ุจูŠุงู†ุงุช (Data Types):
    • ุงู„ู€ string ููŠ C# ุจุชุชุญูˆู„ ู„ู€ nvarchar(max) ููŠ SQL Server (ูŠุนู†ูŠ string ูŠู‚ุฏุฑ ูŠุดูŠู„ ุนุฏุฏ ุญุฑูˆู ูƒุจูŠุฑ ุฌุฏู‹ุง ูˆู…ู…ูƒู† ูŠุฎุฒู† ุญุฑูˆู Unicode).
    • ุงู„ู€ int ุจุชุชุญูˆู„ ู„ู€ int.
    • ุงู„ู€ double ุจุชุชุญูˆู„ ู„ู€ float.
    • ุงู„ู€ decimal ุจุชุชุญูˆู„ ู„ู€ decimal(18, 2) (ุฏู‚ุฉ ู‚ูŠุงุณูŠุฉ).
    • ุงู„ู€ DateTime ุจุชุชุญูˆู„ ู„ู€ datetime2.
    • ูˆู‡ูƒุฐุงโ€ฆ ู„ูƒู„ ู†ูˆุน ุฏุงุชุง ููŠ C# ููŠู‡ ู…ู‚ุงุจู„ ุงูุชุฑุงุถูŠ ููŠ ุงู„ุฏุงุชุงุจูŠุฒ.
  • ุชุญุฏูŠุฏ ุงู„ู€ Nullability (ู‡ู„ ุงู„ู‚ูŠู…ุฉ ู…ู…ูƒู† ุชุจู‚ู‰ ูุงุถูŠุฉุŸ):
    • ุฏูŠ ู†ู‚ุทุฉ ู…ู‡ู…ุฉ ูˆุจุชุนุชู…ุฏ ุนู„ู‰ ุฅุฐุง ูƒู†ุช ู…ุณุชุฎุฏู… Nullable Reference Types ูˆ Nullable Value Types ููŠ C# ูˆู„ุง ู„ุฃ (ุฒูŠ ู…ุง ุงุชูƒู„ู…ู†ุง ููŠ Nullable Types).
    • ุงู„ู‚ุงุนุฏุฉ:
      • ู„ูˆ ุงู„ู€ property ููŠ C# ู…ุด nullable (ุฒูŠ string Name ุฃูˆ double Salary ููŠ ู…ุซุงู„ู†ุง ุงู„ุฃูˆู„)ุŒ ูŠุจู‚ู‰ ุงู„ู€ Column ุงู„ู„ูŠ ู‡ูŠุชุนู…ู„ ููŠ ุงู„ุฏุงุชุงุจูŠุฒ ู‡ูŠุจู‚ู‰ NOT NULL (ุฅุฌุจุงุฑูŠ ู„ุงุฒู… ุชุฏุฎู„ู‡ ู‚ูŠู…ุฉ).
      • ู„ูˆ ุงู„ู€ property ู…ุนู…ูˆู„ุฉ nullable ููŠ C# (ุจุงุณุชุฎุฏุงู… ุนู„ุงู…ุฉ ุงู„ุงุณุชูู‡ุงู… ? ู„ู„ู€ value types ุฒูŠ int? AgeุŒ ุฃูˆ ู„ูˆ ู…ูุนู„ ุงู„ู€ Nullable Reference Types ูˆุงุณุชุฎุฏู…ุช string? ู…ุซู„ู‹ุง)ุŒ ูŠุจู‚ู‰ ุงู„ู€ Column ุงู„ู…ู‚ุงุจู„ ููŠ ุงู„ุฏุงุชุงุจูŠุฒ ู‡ูŠุณู…ุญ ุจู‚ูŠู… NULL (ูŠุนู†ูŠ ุงู„ู‚ูŠู…ุฉ ุงุฎุชูŠุงุฑูŠุฉ Optional).

ุชุทุจูŠู‚ ุงู„ู€ Conventions ุนู„ู‰ ุงู„ู€ Employee Class ุจุชุงุนู†ุง:

ู„ูˆ ุทุจู‚ู†ุง ุงู„ู‚ูˆุงุนุฏ ุฏูŠ ุนู„ู‰ ุงู„ู€ Employee class ุงู„ุฃุตู„ูŠ ุงู„ู„ูŠ ุนู…ู„ู†ุงู‡:

  1. ุงู„ู€ Id (int):
    • ุนุดุงู† ุงุณู…ู‡ุง IdุŒ ู‡ุชุจู‚ู‰ ู‡ูŠ ุงู„ู€ Primary Key.
    • ู‡ุชุจู‚ู‰ Identity (auto-increment).
    • ู†ูˆุน ุงู„ู€ Column ู‡ูŠุจู‚ู‰ int ูˆ ู‡ูŠุจู‚ู‰ NOT NULL.
  2. ุงู„ู€ Name (string):
    • ู‡ุชุจู‚ู‰ Column ู†ูˆุนู‡ nvarchar(max).
    • ู‡ุชุจู‚ู‰ NOT NULL (ู„ูˆ ู…ุด ู…ูุนู„ Nullable Reference TypesุŒ ุฃูˆ ู„ูˆ ู…ูุนู„ู‡ุง ูˆู…ูƒุชุจุชู‡ุงุด string?).
  3. ุงู„ู€ Salary (double):
    • ู‡ุชุจู‚ู‰ Column ู†ูˆุนู‡ float.
    • ู‡ุชุจู‚ู‰ NOT NULL (ู„ุฃู† double ุงู„ุนุงุฏูŠุฉ ู…ุด nullable).
  4. ุงู„ู€ Age (int?):
    • ุนุดุงู† ู…ุณุชุฎุฏู…ูŠู† int? (ูŠุนู†ูŠ nullable value type)ุŒ ุงู„ู€ Column ู‡ูŠุจู‚ู‰ ู†ูˆุนู‡ int.
    • ูˆู‡ูŠุณู…ุญ ุจู‚ูŠู… NULL (ูŠุนู†ูŠ Optional).

ุฎุทูˆุฉ ู…ู‡ู…ุฉ: ุฅุฒุงูŠ ุงู„ู€ Class ุจูŠุชุญูˆู„ ู„ู€ Table ูุนู„ู‹ุงุŸ (ุฏูˆุฑ ุงู„ู€ DbContext)

ุงู„ูƒู„ุงู… ุงู„ู†ุธุฑูŠ ุฏู‡ ุฌู…ูŠู„ุŒ ุจุณ ุงู„ู€ EF Core ู…ุด ู‡ูŠุฑูˆุญ ูŠุฏูˆุฑ ุนู„ู‰ ูƒู„ ุงู„ู€ Classes ููŠ ุงู„ู€ project ุจุชุงุนูƒ ูˆูŠุญูˆู„ู‡ุง ู„ู€ tables ูƒุฏู‡ ูˆุฎู„ุงุต. ู„ุงุฒู… ุชู‚ูˆู„ู‡ ุตุฑุงุญุฉู‹ ุฅูŠู‡ ู‡ูŠ ุงู„ู€ Classes (ุงู„ู€ Entities) ุงู„ู„ูŠ ุฅู†ุช ุนุงูŠุฒู‡ ูŠุชุนุงู…ู„ ู…ุนุงู‡ุง ูƒุฌุฒุก ู…ู† ุงู„ู€ Database Model ุจุชุงุนูƒ.

  • ุงู„ุญู„: ุจู†ุนู…ู„ ุฏู‡ ุนู† ุทุฑูŠู‚ ุฅู†ู†ุง ุจู†ุถูŠู property ู…ู† ู†ูˆุน DbSet<T> ุฌูˆู‡ ุงู„ูƒู„ุงุณ ุงู„ุฃุณุงุณูŠ ุงู„ู„ูŠ ุจูŠู…ุซู„ ุงู„ุฏุงุชุงุจูŠุฒ ุจุชุงุนุชู†ุง ููŠ ุงู„ูƒูˆุฏ.
  • ุงู„ู€ Understanding DbContext in Entity Framework Core: ุงู„ูƒู„ุงุณ ุฏู‡ ุงู„ู„ูŠ ุจูŠุญุชูˆูŠ ุนู„ู‰ ุงู„ู€ DbSet properties ู‡ูˆ ุงู„ู„ูŠ ุจู†ุณู…ูŠู‡ DbContext. ุฏู‡ ูŠุนุชุจุฑ ู‡ูˆ โ€œู…ุฏูŠุฑ ุงู„ุฏุงุชุงุจูŠุฒโ€ ุจุชุงุนูƒ ููŠ ุงู„ูƒูˆุฏุŒ ู‡ูˆ ุงู„ูˆุณูŠุท ุงู„ู„ูŠ ุจูŠู† ุงู„ูƒูˆุฏ ุจุชุงุนูƒ ูˆุจูŠู† ุงู„ุฏุงุชุงุจูŠุฒ ุงู„ูุนู„ูŠุฉ.

ูŠุนู†ูŠุŒ ุนุดุงู† ุงู„ู€ Employee class ูŠุชูู‡ู… ูˆูŠุชุญูˆู„ ู„ู€ tableุŒ ู„ุงุฒู… ู†ุถูŠู ุงู„ุณุทุฑ ุฏู‡ ุฌูˆู‡ ุงู„ู€ DbContext ุจุชุงุนู†ุง:

// Inside your DbContext class (e.g., CompanyDbContext)
public DbSet<Employee> Employees { get; set; }
 
// Comment: We will talk to the 'Employees' table (or view/function)
//          in the database through this 'Employees' property.
 
// Example usage later in code:
// var firstEmployee = dbContext.Employees.FirstOrDefault(E => E.Id == 1);
  • ู„ู…ุง ุจู†ุถูŠู ุงู„ู€ DbSet<Employee> ุฏู‡ุŒ ุงู„ู€ EF Core ูˆู‚ุช ู…ุง ุจูŠุนู…ู„ build ู„ู„ู€ model ุจุชุงุนู‡ุŒ ุจูŠุดูˆู ุงู„ู€ property ุฏูŠ ูˆุจูŠูู‡ู… ุฅู†ู‡ ู…ุทู„ูˆุจ ู…ู†ู‡ ูŠุนู…ู„ mapping ู„ู„ู€ Employee class. ูˆุณุงุนุชู‡ุง ุจูŠุฑูˆุญ ูŠุทุจู‚ ู‚ูˆุงุนุฏ ุงู„ู€ Convention (ุฃูˆ ุฃูŠ ุทุฑูŠู‚ุฉ mapping ุชุงู†ูŠุฉ ุฅู†ุช ู…ุญุฏุฏู‡ุง) ุนุดุงู† ูŠุนุฑู ุดูƒู„ ุงู„ู€ Table ุฏู‡ ุงู„ู…ูุฑูˆุถ ูŠุจู‚ู‰ ุฅูŠู‡.
  • ู„ูŠู‡ ุงุณู…ู‡ุง DbSetุŸ ุงู„ุงุณู… ุฏู‡ ู…ุฑู† ุดูˆูŠุฉุŒ ู„ุฃู† ุงู„ู€ DbSet ู…ุด ุดุฑุท ูŠู…ุซู„ Table ุจุณุŒ ู…ู…ูƒู† ููŠ ุณูŠู†ุงุฑูŠูˆู‡ุงุช ู…ุชู‚ุฏู…ุฉ ู†ุฎู„ูŠู‡ ูŠุนู…ู„ map ู„ู€ View ููŠ ุงู„ุฏุงุชุงุจูŠุฒ ุฃูˆ ุญุชู‰ ูŠุณุชุฎุฏู… Table-Valued Function (TVF) ูƒู…ุตุฏุฑ ู„ู„ุฏุงุชุง. ุจุณ ููŠ ุงู„ุฃุบู„ุจ ุจู†ุณุชุฎุฏู…ู‡ ุนุดุงู† ู†ู…ุซู„ Tables.

ุงู„ุฎู„ุงุตุฉ: ุทุฑูŠู‚ุฉ ุงู„ู€ Convention ู‡ูŠ ุงู„ุฃุณุงุณ ูˆุงู„ุจุฏุงูŠุฉ. ุจุชูƒุชุจ ุงู„ู€ POCO classes ุจุชุงุนุชูƒ ุจุดูƒู„ ู‚ูŠุงุณูŠุŒ ูˆุชุถูŠู ู„ู‡ุง DbSet ููŠ ุงู„ู€ DbContextุŒ ูˆุงู„ู€ EF Core ุจูŠู‚ูˆู… ุจุงู„ุจุงู‚ูŠ ุจุดูƒู„ ุงูุชุฑุงุถูŠ.

ุทูŠุจ ู„ูˆ ุงู„ุงูุชุฑุงุถุงุช ุฏูŠ ู…ุด ู…ู†ุงุณุจุฉุŸ ู„ูˆ ุนุงูŠุฒ ุงุณู… ุงู„ู€ Table ูŠุจู‚ู‰ ู…ุฎุชู„ูุŸ ู„ูˆ ุนุงูŠุฒ ุงุณู… Column ูŠุจู‚ู‰ ู…ุฎุชู„ูุŸ ู„ูˆ ุนุงูŠุฒ ู†ูˆุน ุฏุงุชุง ู…ุนูŠู† ููŠ ุงู„ุฏุงุชุงุจูŠุฒ ู…ุด ู‡ูˆ ุงู„ุงูุชุฑุงุถูŠุŸ ู„ูˆ ุนุงูŠุฒ Primary Key ูŠุจู‚ู‰ ู…ุด IdุŸ ู‡ู†ุง ุจู†ุญุชุงุฌ ู†ู†ุชู‚ู„ ู„ู„ุทุฑูŠู‚ุฉ ุงู„ุชุงู†ูŠุฉ.

2. Data Annotation

ุฏูŠ ุงู„ุทุฑูŠู‚ุฉ ุงู„ุชุงู†ูŠุฉ ุนุดุงู† ู†ุฎุตุต ุงู„ู€ mapping ุงู„ู„ูŠ ุจูŠุญุตู„ By Convention.

  • ุงู„ููƒุฑุฉ: ุจู†ุณุชุฎุฏู… ุญุงุฌุฉ ุงุณู…ู‡ุง Attributes ููŠ C#. ุงู„ู€ Attribute ุฏู‡ ุจูŠุจู‚ู‰ ุฒูŠ โ€œุนู„ุงู…ุฉโ€ ุฃูˆ โ€œุชุงุฌโ€ ุจู†ุญุทู‡ ููˆู‚ ุงู„ู€ Class ู†ูุณู‡ ุฃูˆ ููˆู‚ ุงู„ู€ Properties ุจุชุงุนุชู‡ ุนุดุงู† ู†ุฏูŠ ุชุนู„ูŠู…ุงุช ุฒูŠุงุฏุฉ ู„ู„ู€ EF Core.

  • ูƒู†ุง ุงุณุชุฎุฏู…ู†ุง Attribute ู„ูˆ ูุงูƒุฑ ููŠ Bit Flags with Enum

  • ุฏุง ุจูŠูุชุญู„ู†ุง ูƒู„ุงู… ูƒุชูŠุฑ ููŠ ุงู„ู€ Reflection

  • ุงู„ุงุณุชุฎุฏุงู… ุงู„ุฃุณุงุณูŠ:

    1. ุชุฎุตูŠุต ุงู„ู€ Mapping: ู†ู‚ูˆู„ ู„ู„ู€ EF Core ูŠุนู…ู„ ุญุงุฌุงุช ุบูŠุฑ ุงู„ู„ูŠ ูƒุงู† ู‡ูŠุนู…ู„ู‡ุง By Convention (ุฒูŠ ุชุบูŠูŠุฑ ุงุณู… Table ุฃูˆ ColumnุŒ ุชุญุฏูŠุฏ ู†ูˆุน ุฏุงุชุง ู…ุนูŠู†ุŒ ุชุญุฏูŠุฏ ุงู„ู€ Primary Key ุตุฑุงุญุฉู‹ุŒ ุฅู„ุฎ).
    2. ุนู…ู„ Data Validation: ูƒุชูŠุฑ ู…ู† ุงู„ู€ Data Annotations ุฏูŠ ู„ูŠู‡ุง ุฏูˆุฑ ู…ุฒุฏูˆุฌุŒ ู…ุด ุจุณ ุจุชุฃุซุฑ ุนู„ู‰ ุงู„ุฏุงุชุงุจูŠุฒุŒ ุฏูŠ ูƒู…ุงู† ุจุชุณุชุฎุฏู… ุนุดุงู† ู†ุญุท ู‚ูˆุงุนุฏ ู„ู„ุชุญู‚ู‚ ู…ู† ุตุญุฉ ุงู„ุจูŠุงู†ุงุช (Validation Rules) ุงู„ู„ูŠ ุงู„ูŠูˆุฒุฑ ุจูŠุฏุฎู„ู‡ุง.
  • ุฒูŠ ู…ุง ู‚ูˆู„ู†ุงุŒ ุงู„ุทุฑู‚ ุจุชูƒู…ู„ ุจุนุถ: ุจู†ุจุฏุฃ ุจุงู„ู€ ConventionุŒ ูˆู„ูˆ ููŠู‡ ุญุงุฌุฉ ู…ุญุชุงุฌุฉ ุชุชุบูŠุฑุŒ ุจู†ุณุชุฎุฏู… Data Annotation ุนุดุงู† ู†ุบูŠุฑู‡ุง.

ู…ุซุงู„: ุชุนุฏูŠู„ ุงู„ู€ Employee Class ุจุงุณุชุฎุฏุงู… Data Annotations

ู„ู†ูุชุฑุถ ุฅู†ู†ุง ุนุงูŠุฒูŠู† ู†ุนู…ู„ ุงู„ุชุนุฏูŠู„ุงุช ุฏูŠ ุนู„ู‰ ุงู„ู€ Employee class:

  • ู†ุบูŠุฑ ุงุณู… ุงู„ู€ Primary Key property ู…ู† Id ู„ู€ EmpId.
  • ู†ุฎู„ูŠ ุงู„ู€ Name ู…ุทู„ูˆุจ (Required) ูˆุฃู‚ุตู‰ ุทูˆู„ ู„ูŠู‡ 100 ุญุฑู ุจุณ (ุจุฏู„ nvarchar(max)).
  • ู†ุฎู„ูŠ ู†ูˆุน ุงู„ู€ Salary ููŠ ุงู„ุฏุงุชุงุจูŠุฒ ูŠุจู‚ู‰ decimal(18, 2) ุนุดุงู† ุงู„ุฏู‚ุฉ (ุจุฏู„ float).
  • ู†ุถูŠู ู‚ุงุนุฏุฉ validation ุฅู† ุงู„ู€ Age ู„ุงุฒู… ูŠูƒูˆู† ุจูŠู† 18 ูˆ 65.
  • ู†ุถูŠู property ุฒูŠุงุฏุฉ ููŠ ุงู„ูƒู„ุงุณ ุงุณู…ู‡ุง FullInfo ุจุชุนุฑุถ ุงู„ุงุณู… ูˆุงู„ุนู…ุฑ ู…ุน ุจุนุถุŒ ุจุณ ู…ุด ุนุงูŠุฒูŠู†ู‡ุง ุชุชุฎุฒู† ููŠ ุงู„ุฏุงุชุงุจูŠุฒ.

ุงู„ูƒู„ุงุณ ู‡ูŠุจู‚ู‰ ุดูƒู„ู‡ ูƒุฏู‡ (ู‡ู†ุญุชุงุฌ ู†ุนู…ู„ using ู„ู€ namespaces ู…ุนูŠู†ุฉ):

// Need: using System.ComponentModel.DataAnnotations;
// Need: using System.ComponentModel.DataAnnotations.Schema;
 
// Example: Let's map this class to a table named "EmployeesInfo" in the "hr" schema
[Table("EmployeesInfo", Schema = "hr")]
internal class Employee
{
    // [Key] explicitly defines the Primary Key
    [Key]
    // [DatabaseGenerated(Identity)] specifies auto-increment behavior
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int EmpId { get; set; } // Name changed, convention won't find PK anymore
 
    // [Required] makes the DB column NOT NULL and adds validation
    [Required(ErrorMessage = "Employee name is mandatory.")]
    // [MaxLength] limits DB column size and adds validation
    [MaxLength(100)]
    public string Name { get; set; }
 
    // [Column] allows specifying exact DB TypeName
    [Column(TypeName = "decimal(18, 2)")]
    public double Salary { get; set; } // Still double in C#, but maps to decimal in DB
 
    // [Range] primarily for validation, doesn't usually affect DB schema directly
    [Range(18, 65, ErrorMessage = "Age must be between 18 and 65.")]
    public int? Age { get; set; }
 
    // [NotMapped] tells EF Core to completely ignore this property for DB mapping
    [NotMapped]
    public string FullInfo { get { return $"{Name} ({(Age.HasValue ? Age.Value.ToString() : "N/A")})"; } }
 
    // Example: Using DataType for hints (often for UI/Validation)
    // [DataType(DataType.Currency)] // Hint for UI
    // public decimal Bonus { get; set; } // Let's assume we added a Bonus property
 
    // Example: Using EmailAddress validation shortcut
    // [EmailAddress]
    // public string WorkEmail { get; set; }
}

ุดุฑุญ ุงู„ู€ Attributes (ุงู„ุนู„ุงู…ุงุช) ุงู„ู„ูŠ ุงุณุชุฎุฏู…ู†ุงู‡ุง:

  • ุงู„ู€ [Key]:
    • ุงู„ูˆุธูŠูุฉ: ุจุชู‚ูˆู„ ู„ู„ู€ EF Core ุตุฑุงุญุฉู‹: โ€œุงู„ู€ property ุฏูŠ ู‡ูŠ ุงู„ู€ Primary Keyโ€. ุงุณุชุฎุฏู…ู†ุงู‡ุง ู‡ู†ุง ู„ุฃู†ู†ุง ุบูŠุฑู†ุง ุงู„ุงุณู… ู…ู† Id ู„ู€ EmpIdุŒ ูุงู„ู€ Convention ู…ุจู‚ุชุด ุนุงุฑูุฉ ุชุญุฏุฏ ุงู„ู€ PK ู„ูˆุญุฏู‡ุง.
    • ุงู„ู…ูƒุงู†: ููˆู‚ ุงู„ู€ property ุงู„ู„ูŠ ุนุงูŠุฒู‡ุง ุชุจู‚ู‰ PK.
    • ุงู„ู€ Namespace: System.ComponentModel.DataAnnotations.
  • ุงู„ู€ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]:
    • ุงู„ูˆุธูŠูุฉ: ุจุชู‚ูˆู„ ู„ู„ู€ EF Core ุฅุฒุงูŠ ู‚ูŠู…ุฉ ุงู„ู€ property ุฏูŠ ุจุชุชุฌุงุจ.
    • ุงู„ู€ DatabaseGeneratedOption.Identity: ู…ุนู†ุงู‡ุง ุฅู† ุงู„ุฏุงุชุงุจูŠุฒ ู‡ูŠ ุงู„ู„ูŠ ู…ุณุฆูˆู„ุฉ ุนู† ุชูˆู„ูŠุฏ ุงู„ู‚ูŠู…ุฉ ุฏูŠุŒ ูˆุบุงู„ุจู‹ุง ุจุชูƒูˆู† ุนู† ุทุฑูŠู‚ auto-increment (ุฒูŠุงุฏุฉ ุชู„ู‚ุงุฆูŠุฉ).
    • ุฎูŠุงุฑุงุช ุชุงู†ูŠุฉ:
      • ุงู„ู€ None: ู…ุนู†ุงู‡ุง ุฅู† ุงู„ุฏุงุชุงุจูŠุฒ ู…ู„ู‡ุงุด ุฏุนูˆุฉ ุจุชูˆู„ูŠุฏ ุงู„ู‚ูŠู…ุฉุŒ ูˆุฅู†ุช ุงู„ู„ูŠ ู‡ุชุฏุฎู„ู‡ุง ู…ู† ุงู„ูƒูˆุฏ ุจุชุงุนูƒ (ู…ุซู„ู‹ุง ู„ูˆ ุงู„ู€ PK ู…ุด ุฑู‚ู… ุจูŠุฒูŠุฏ ู„ูˆุญุฏู‡ุŒ ุฒูŠ GUID ุฃูˆ ุฑู‚ู… ู‚ูˆู…ูŠ). ู…ู…ูƒู† ุชุณุชุฎุฏู… ุฏูŠ ู„ูˆ ุงู„ู€ Convention ูƒุงู†ุช ู‡ุชุฎู„ูŠู‡ุง Identity ูˆุฅู†ุช ู…ุด ุนุงูŠุฒ ูƒุฏู‡.
      • ุงู„ู€ Computed: ู…ุนู†ุงู‡ุง ุฅู† ุงู„ู‚ูŠู…ุฉ ุฏูŠ ุจุชุชุญุณุจ ุฌูˆู‡ ุงู„ุฏุงุชุงุจูŠุฒ ู†ูุณู‡ุงุŒ ุจู†ุงุกู‹ ุนู„ู‰ columns ุชุงู†ูŠุฉ (ุฒูŠ Computed Column ููŠ SQL Server). ู…ุซุงู„ ุจุณูŠุท: ู„ูˆ ุนู†ุฏูƒ FirstName ูˆ LastName ูˆุนุงูŠุฒ ุชุนู…ู„ column ุงุณู…ู‡ FullName ุจูŠุชุญุณุจ ุชู„ู‚ุงุฆูŠ ููŠ ุงู„ุฏุงุชุงุจูŠุฒ. (ู…ู„ุญูˆุธุฉ: ุชุญุฏูŠุฏ ุงู„ู€ formula ู†ูุณู‡ุง ุบุงู„ุจู‹ุง ุจูŠุญุชุงุฌ ุงู„ุทุฑูŠู‚ุฉ ุงู„ุชุงู„ุชุฉ ู„ู„ู€ Mapping ุงู„ู„ูŠ ู‡ูŠ Fluent API).
  • ุงู„ู€ [Required]:
    • ุงู„ูˆุธูŠูุฉ: ู„ูŠู‡ุง ุฏูˆุฑูŠู†:
      1. ุงู„ู€ Schema: ุจุชุฎู„ูŠ ุงู„ู€ Column ููŠ ุงู„ุฏุงุชุงุจูŠุฒ ูŠุจู‚ู‰ NOT NULL.
      2. ุงู„ู€ Validation: ุจุชุณุชุฎุฏู… ููŠ ุงู„ู€ frameworks ุฒูŠ ASP.NET Core ุนุดุงู† ุชุชุฃูƒุฏ ุฅู† ุงู„ูŠูˆุฒุฑ ุฏุฎู„ ู‚ูŠู…ุฉ ู„ู„ู€ field ุฏู‡ ูˆู…ุชุณุงุจูˆุด ูุงุถูŠ. ู…ู…ูƒู† ุชุญุท ErrorMessage ุนุดุงู† ุชุธู‡ุฑ ุฑุณุงู„ุฉ ู…ุนูŠู†ุฉ ู„ู„ูŠูˆุฒุฑ.
  • ุงู„ู€ [MaxLength(100)]:
    • ุงู„ูˆุธูŠูุฉ: ู„ูŠู‡ุง ุฏูˆุฑูŠู†:
      1. ุงู„ู€ Schema: ุจุชุญุฏุฏ ุฃู‚ุตู‰ ุนุฏุฏ ุญุฑูˆู ู„ู„ู€ column ููŠ ุงู„ุฏุงุชุงุจูŠุฒ (ู…ุซู„ู‹ุง ู‡ุชุนู…ู„ู‡ุง nvarchar(100) ุจุฏู„ nvarchar(max) ุงู„ุงูุชุฑุงุถูŠ).
      2. ุงู„ู€ Validation: ุจุชุณุชุฎุฏู… ุนุดุงู† ุชุชุฃูƒุฏ ุฅู† ุงู„ูŠูˆุฒุฑ ู…ุฏุฎู„ุด ุญุฑูˆู ุฃูƒุชุฑ ู…ู† ุงู„ู…ุณู…ูˆุญ.
  • ุงู„ู€ [StringLength(max, MinimumLength = min)]:
    • ุงู„ูˆุธูŠูุฉ: ุฒูŠ MaxLength ุจุณ ู…ู…ูƒู† ุชุญุฏุฏ ูƒู…ุงู† ุฃู‚ู„ ุนุฏุฏ ุญุฑูˆู ู…ุณู…ูˆุญ ุจูŠู‡ (MinimumLength). ุฏูŠ ุจุชุณุชุฎุฏู… ุฃูƒุชุฑ ู„ู„ู€ Validation.
  • ุงู„ู€ [Column(TypeName = "decimal(18, 2)")]:
    • ุงู„ูˆุธูŠูุฉ: ุจุชุณู…ุญู„ูƒ ุชุญุฏุฏ ู†ูˆุน ุงู„ุฏุงุชุง ุจุชุงุน ุงู„ู€ Column ููŠ ุงู„ุฏุงุชุงุจูŠุฒ ุจุงู„ุธุจุท ุฒูŠ ู…ุง ุฅู†ุช ุนุงูŠุฒู‡ (ู…ุซู„ู‹ุง decimal(18, 2) ุฃูˆ varchar(50) ุฃูˆ date).
  • ุงู„ู€ [Range(18, 65)]:
    • ุงู„ูˆุธูŠูุฉ: ุฏูŠ ุฃุณุงุณู‹ุง ู„ู„ู€ Validation. ุจุชุญุฏุฏ ุฅู† ุงู„ู‚ูŠู…ุฉ ุงู„ุฑู‚ู…ูŠุฉ (ุฃูˆ ุงู„ุชุงุฑูŠุฎ) ู„ุงุฒู… ุชูƒูˆู† ููŠ ู†ุทุงู‚ ู…ุนูŠู†. ู…ุด ุจุชุบูŠุฑ ุงู„ู€ Schema ุจุชุงุน ุงู„ุฏุงุชุงุจูŠุฒ ููŠ ุงู„ุนุงุฏูŠ. ู…ู…ูƒู† ุชุญุท ErrorMessage.
  • ุงู„ู€ [DataType(DataType...)]:
    • ุงู„ูˆุธูŠูุฉ: ุจุชุฏูŠ ู…ุนู„ูˆู…ุฉ ุฅุถุงููŠุฉ ุนู† ุทุจูŠุนุฉ ุงู„ุฏุงุชุง (ุฒูŠ DataType.Currency, DataType.EmailAddress, DataType.Password, DataType.Date). ุฏูŠ ุจุชุณุชุฎุฏู… ุฃูƒุชุฑ ู„ู„ู€ Validation ูˆุนุดุงู† ุงู„ู€ UI frameworks ุชุนุฑู ุชุนุฑุถ input field ู…ู†ุงุณุจ (ู…ุซู„ู‹ุง ุชุนุฑุถ ุฑู…ุฒ ุงู„ุนู…ู„ุฉุŒ ุฃูˆ ุชุฎู„ูŠ ุงู„ู€ input ุจุชุงุน ุงู„ุจุงุณูˆุฑุฏ ู†ุฌูˆู…). ููŠ ุงู„ุบุงู„ุจ ู…ุด ุจุชุบูŠุฑ ู†ูˆุน ุงู„ู€ column ููŠ ุงู„ุฏุงุชุงุจูŠุฒ ู„ูˆุญุฏู‡ุงุŒ ู„ูˆ ุนุงูŠุฒ ุชุบูŠุฑ ู†ูˆุน ุงู„ุฏุงุชุงุจูŠุฒ ุงุณุชุฎุฏู… [Column(TypeName = "...")] ู…ุนุงู‡ุง.
  • ุงู„ู€ [EmailAddress], [Phone], [CreditCard]:
    • ุงู„ูˆุธูŠูุฉ: ุฏูŠ ุงุฎุชุตุงุฑุงุช ู„ู€ [DataType] ูˆุจุชุถูŠู validation ุฌุงู‡ุฒุฉ ุนุดุงู† ุชุชุฃูƒุฏ ุฅู† ุงู„ููˆุฑู…ุงุช ุจุชุงุนุช ุงู„ุฅูŠู…ูŠู„ ุฃูˆ ุงู„ุชู„ูŠููˆู† ุฃูˆ ุงู„ูƒุฑูŠุฏุช ูƒุงุฑุฏ ุตุญ.
  • ุงู„ู€ [NotMapped]:
    • ุงู„ูˆุธูŠูุฉ: ู…ู‡ู…ุฉ ุฌุฏู‹ุง. ุจุชู‚ูˆู„ ู„ู„ู€ EF Core: โ€œุงู„ู€ property ุฏูŠ ุชุฌุงู‡ู„ู‡ุง ุฎุงู„ุตุŒ ู…ุชุนู…ู„ู‡ุงุด map ู„ุฃูŠ column ููŠ ุงู„ุฏุงุชุงุจูŠุฒโ€. ุจู†ุณุชุฎุฏู…ู‡ุง ู„ู„ู€ helper properties ุงู„ู„ูŠ ุจู†ุญุณุจู‡ุง ููŠ ุงู„ูƒูˆุฏ ุจุณ ูˆู…ุด ุนุงูŠุฒูŠู† ู†ุฎุฒู†ู‡ุง.
  • ุงู„ู€ [Table("EmployeesInfo", Schema = "hr")]:
    • ุงู„ูˆุธูŠูุฉ:
      1. ุจุชุฎู„ูŠูƒ ุชุบูŠุฑ ุงุณู… ุงู„ู€ Table ููŠ ุงู„ุฏุงุชุงุจูŠุฒ (ู‡ู†ุง ู‡ูŠุจู‚ู‰ EmployeesInfo ุจุฏู„ ุงู„ุงุณู… ุงู„ุงูุชุฑุงุถูŠ ุงู„ู„ูŠ ู…ู…ูƒู† ูŠูƒูˆู† Employee ุฃูˆ Employees).
      2. ุจุชุฎู„ูŠูƒ ุชุญุฏุฏ ุงู„ู€ Schema ุงู„ู„ูŠ ุงู„ู€ Table ุฏู‡ ู‡ูŠุชุญุท ุฌูˆุงู‡ (ู‡ู†ุง hr ุจุฏู„ ุงู„ู€ schema ุงู„ุงูุชุฑุงุถูŠ ุงู„ู„ูŠ ู‡ูˆ ุบุงู„ุจู‹ุง dbo). ุฏูŠ ู…ูŠุฒุฉ ู…ู‡ู…ุฉ ู…ุด ุจู†ู‚ุฏุฑ ู†ุนู…ู„ู‡ุง ุจุณู‡ูˆู„ุฉ ุจุงู„ู€ Convention.
    • ุงู„ู…ูƒุงู†: ููˆู‚ ุงู„ู€ Class ู†ูุณู‡.

ู‡ู„ [Table] ูŠุบู†ูŠ ุนู† DbSetุŸ

ุณุคุงู„ ูƒูˆูŠุณ: ู„ูˆ ุฃู†ุง ุงุณุชุฎุฏู…ุช ุงู„ู€ [Table] attribute ุนุดุงู† ุฃุญุฏุฏ ุงุณู… ุงู„ู€ Table ูˆุงู„ู€ SchemaุŒ ู‡ู„ ุฏู‡ ู…ุนู†ุงู‡ ุฅู†ูŠ ู…ุด ู…ุญุชุงุฌ ุฃูƒุชุจ DbSet<Employee> ุฌูˆู‡ ุงู„ู€ DbContextุŸ

  • ุงู„ุฅุฌุงุจุฉ ู…ู† ู†ุงุญูŠุฉ ุชู‚ู†ูŠุฉ: ู„ุงุŒ ู…ุด ู…ู…ูƒู†. ุงู„ู€ DbSet ุถุฑูˆุฑูŠ ุนุดุงู† ุงู„ู€ EF Core ูŠุนุฑู ุฅู† ุงู„ู€ Class ุฏู‡ ุฌุฒุก ู…ู† ุงู„ู€ Model ุงู„ู„ูŠ ุนุงูŠุฒ ูŠุฏูŠุฑู‡ ูˆูŠุชุนุงู…ู„ ู…ุนุงู‡. ุงู„ู€ [Table] attribute ุจูŠุณุชุฎุฏู… ูู‚ุท ุนุดุงู† ูŠุนู…ู„ override ู„ู„ู€ convention ุงู„ุฎุงุตุฉ ุจุงุณู… ุงู„ู€ table ูˆุงู„ู€ schemaุŒ ู„ูƒู† ู…ุด ุจูŠุบู†ูŠ ุนู† ุชุนุฑูŠู ุงู„ู€ Entity ู„ู„ู€ DbContext ุนู† ุทุฑูŠู‚ DbSet. ู„ุงุฒู… ุชุนู…ู„ DbSet ุฏุงูŠู…ู‹ุง.

ุฃู‡ู…ูŠุฉ ุงู„ู€ Data Annotations ููŠ ุงู„ู€ Validation

ุฒูŠ ู…ุง ุดูˆูู†ุงุŒ ูƒุชูŠุฑ ู…ู† ุงู„ู€ Annotations ุฏูŠ ู„ูŠู‡ุง ุฏูˆุฑ ุญูŠูˆูŠ ููŠ ุนู…ู„ูŠุฉ ุงู„ู€ Validation (ุงู„ุชุญู‚ู‚ ู…ู† ุตุญุฉ ุงู„ุจูŠุงู†ุงุช).

  • ุงู„ู€ Validation ู†ูˆุนูŠู† ุฃุณุงุณูŠูŠู† (Application Validation):
    • ุงู„ู€ Front-end Validation (ููŠ ุงู„ู…ุชุตูุญ): ุจุชุญุตู„ ุนู†ุฏ ุงู„ูŠูˆุฒุฑ ู‚ุจู„ ู…ุง ูŠุจุนุช ุงู„ุฏุงุชุง ู„ู„ุณูŠุฑูุฑ. ูุงูŠุฏุชู‡ุง ุฅู†ู‡ุง ุณุฑูŠุนุฉุŒ ุจุชุฏูŠ ููŠุฏุจุงูƒ ููˆุฑูŠ ู„ู„ูŠูˆุฒุฑ (ุฒูŠ โ€œู…ูŠู†ูุนุด ุชุณูŠุจ ุงู„ุฎุงู†ุฉ ุฏูŠ ูุงุถูŠุฉโ€)ุŒ ูˆุจุชู‚ู„ู„ ุงู„ุฑูŠูƒูˆุณุชุงุช ุงู„ุบู„ุท ุงู„ู„ูŠ ุฑุงูŠุญุฉ ู„ู„ุณูŠุฑูุฑ.
    • ุงู„ู€ Back-end Validation (ุนู„ู‰ ุงู„ุณูŠุฑูุฑ): ุจุชุญุตู„ ู„ู…ุง ุงู„ุฏุงุชุง ุชูˆุตู„ ู„ู„ุณูŠุฑูุฑ ุจุชุงุนูƒ. ูˆุฏูŠ ุงู„ุฃู‡ู… ูˆุงู„ุฃุณุงุณ ุงู„ู„ูŠ ู…ูŠู†ูุนุด ู†ุณุชุบู†ู‰ ุนู†ู‡. ู„ูŠู‡ุŸ ู„ุฃู† ุฃูŠ ุญุฏ ู…ู…ูƒู† ุจุณู‡ูˆู„ุฉ ูŠุชุฎุทู‰ ุงู„ู€ front-end validation (ู…ุซู„ู‹ุง ูŠู‚ูู„ ุงู„ู€ JavaScript ุฃูˆ ูŠุณุชุฎุฏู… ุฃุฏูˆุงุช ุฒูŠ Postman). ุงู„ู€ Back-end validation ู‡ูŠ ุงู„ุถู…ุงู† ุงู„ุฃุฎูŠุฑ ุฅู† ุงู„ุฏุงุชุง ุงู„ู„ูŠ ู‡ุชุฏุฎู„ ุงู„ุฏุงุชุงุจูŠุฒ ุจุชุงุนุชูƒ ุณู„ูŠู…ุฉ ูˆู…ุทุงุจู‚ุฉ ู„ู„ู‚ูˆุงุนุฏ.
  • ู„ูŠู‡ ุจู†ุนู…ู„ ุงู„ุงุชู†ูŠู†ุŸ ุจู†ุนู…ู„ Front-end ุนุดุงู† ู†ุญุณู† ุชุฌุฑุจุฉ ุงู„ู…ุณุชุฎุฏู… (UX)ุŒ ูˆุจู†ุนู…ู„ Back-end ุนุดุงู† ุงู„ุฃู…ุงู† ูˆุชุฃูƒูŠุฏ ุณู„ุงู…ุฉ ุงู„ุจูŠุงู†ุงุช (Data Integrity).
  • ููŠู† ุฏูˆุฑ ุงู„ู€ Data Annotations ู‡ู†ุงุŸ ููŠ ุงู„ู€ frameworks ุงู„ุญุฏูŠุซุฉ ุฒูŠ ASP.NET Core (MVC, Razor Pages, Blazor, API)ุŒ ุงู„ู€ Data Annotations ุงู„ู„ูŠ ุจู†ุญุทู‡ุง ุนู„ู‰ ุงู„ู€ Model classes ุจุชุงุนุชู†ุง (ุฒูŠ Employee) ู„ูŠู‡ุง ูุงูŠุฏุฉ ู…ุฒุฏูˆุฌุฉ ุฑุงุฆุนุฉ:
    • ุงู„ู€ Framework ุจูŠู‚ุฏุฑ ูŠู‚ุฑุฃ ุงู„ู€ Annotations ุฏูŠ ูˆูŠุณุชุฎุฏู…ู‡ุง ุนุดุงู† ูŠุนู…ู„ generate ู„ู€ validation scripts ุชุดุชุบู„ ููŠ ุงู„ู€ front-end (ุบุงู„ุจู‹ุง JavaScript) ุชู„ู‚ุงุฆูŠู‹ุง.
    • ูˆููŠ ู†ูุณ ุงู„ูˆู‚ุชุŒ ุงู„ู€ Framework ุจูŠุณุชุฎุฏู… ู†ูุณ ุงู„ู€ Annotations ุฏูŠ ุนุดุงู† ูŠุนู…ู„ validation ู„ู„ุฏุงุชุง ู„ู…ุง ุชูˆุตู„ ู„ู„ู€ back-end (ุนู„ู‰ ุงู„ุณูŠุฑูุฑ)ุŒ ูˆุฏู‡ ุจูŠุญุตู„ ุบุงู„ุจู‹ุง ูƒุฌุฒุก ู…ู† ุนู…ู„ูŠุฉ ุงู„ู€ Model Binding ู‚ุจู„ ู…ุง ุงู„ุฏุงุชุง ุชูˆุตู„ ู„ู„ู€ Action method ุจุชุงุนุชูƒ.
    • ูŠุนู†ูŠ ุจุชูƒุชุจ ุงู„ู‚ุงุนุฏุฉ ู…ุฑุฉ ูˆุงุญุฏุฉ ุจุงู„ู€ AnnotationุŒ ูˆู‡ูŠ ุจุชุณุชุฎุฏู… ููŠ ุงู„ู†ุงุญูŠุชูŠู†.
  • ู‡ู„ ุฏูŠ validation ุจุชุงุนุฉ MVCุŸ ุฃูŠูˆุฉุŒ ุงู„ู€ Data Annotations ู‡ูŠ ุงู„ุทุฑูŠู‚ุฉ ุงู„ุฃุณุงุณูŠุฉ ูˆุงู„ุฑุณู…ูŠุฉ ู„ุชุนุฑูŠู ู‚ูˆุงุนุฏ ุงู„ู€ validation ููŠ ASP.NET Core. ูˆุงู„ู€ validation ุงู„ู„ูŠ ุจูŠุญุตู„ ุนู„ู‰ ุงู„ุณูŠุฑูุฑ ุจุงุณุชุฎุฏุงู… ุงู„ู€ Annotations ุฏูŠ ูŠุนุชุจุฑ ุฌุฒุก ุฃุณุงุณูŠ ู…ู† ุงู„ู€ back-end validation.
  • ุจุณ ู…ุด ุตุญ ุงู† ุฃุนู…ู„ Validation ู„ู„ูุฑูˆู†ุช ุจุณ ููŠ ุงู„ู€ Domain Model ุงู„ู„ูŠ ุจู†ู‚ูˆู„ ุนู„ูŠู‡ POCO Class ู„ุฃู† ุฏูŠ ุงู„ู…ูุฑูˆุถ ูƒู„ู‡ุง ุญุงุฌุงุช ุชุชุญูˆู„ ููŠ ุงู„ู€ Database ุฅู†ู…ุง ุงู„ู…ูุฑูˆุถ ูŠุจู‚ุง ุฌูˆุง View Model.

ู…ู„ุฎุต ู„ุฃุดู‡ุฑ ุงู„ู€ Data Annotations (ุจุงุฎุชุตุงุฑ ูˆู…ู† ุบูŠุฑ ุญุดูˆ)

Annotationุงู„ุบุฑุถ ุงู„ุฃุณุงุณูŠุงู„ุชุฃุซูŠุฑ ุงู„ุฃุณุงุณูŠ
[Key]ุชุญุฏูŠุฏ ุงู„ู€ Primary KeySchema
[Required]ู…ุทู„ูˆุจ (NOT NULL ููŠ DBุŒ ูˆุฅุฌุจุงุฑูŠ ููŠ ุงู„ุฅุฏุฎุงู„)Schema & Validation
[MaxLength(n)]ุฃู‚ุตู‰ ุทูˆู„ ู„ู„ุญุฑูˆูSchema & Validation
[StringLength(max, Min=min)]ุฃู‚ุตู‰ ูˆุฃู‚ู„ ุทูˆู„ ู„ู„ุญุฑูˆูValidation
[Range(min, max)]ุชุญุฏูŠุฏ ู…ุฏู‰ ู…ู‚ุจูˆู„ ู„ู„ุฃุฑู‚ุงู…/ุงู„ุชูˆุงุฑูŠุฎValidation
[RegularExpression("...")]ู…ุทุงุจู‚ุฉ ู†ู…ุท ู…ุนูŠู† (regex)Validation
[EmailAddress], [Phone]ุงู„ุชุญู‚ู‚ ู…ู† ููˆุฑู…ุงุช ุงู„ุฅูŠู…ูŠู„/ุงู„ุชู„ูŠููˆู†Validation
[Compare("OtherProp")]ู…ู‚ุงุฑู†ุฉ ู‚ูŠู…ุฉ ุจู€ property ุชุงู†ูŠุฉ (ุฒูŠ ุชุฃูƒูŠุฏ ุงู„ุจุงุณูˆุฑุฏ)Validation
[DataType(DataType...)]ุชุญุฏูŠุฏ ู†ูˆุน ุงู„ุฏุงุชุง (hint ู„ู„ู€ UI/Validation)Validation
[Timestamp]ู„ุนู…ู„ Row Versioning (ุชุชุจุน ุงู„ุชุนุฏูŠู„ุงุช ู„ู„ู€ Concurrency)Schema
[ConcurrencyCheck]ุงุณุชุฎุฏุงู… ุงู„ู€ column ุฏู‡ ููŠ ุงู„ู€ Optimistic Concurrency CheckSchema
[Column(TypeName="...", Order=n)]ุชุญุฏูŠุฏ ู†ูˆุน/ุชุฑุชูŠุจ ุงู„ู€ column ููŠ DBSchema
[Table("...", Schema="...")]ุชุญุฏูŠุฏ ุงุณู… ุงู„ู€ Table ูˆุงู„ู€ SchemaSchema
[ForeignKey("NavProp")]ุชุญุฏูŠุฏ ุงู„ู€ Foreign Key ุงู„ู…ุฑุชุจุท ุจู€ Navigation PropertySchema (Relation)
[InverseProperty("...")]ุชุญุฏูŠุฏ ุงู„ู€ Navigation Property ุงู„ู…ู‚ุงุจู„ ููŠ ุงู„ุทุฑู ุงู„ุชุงู†ูŠ ู…ู† ุงู„ุนู„ุงู‚ุฉ (1-*)Schema (Relation)
[DatabaseGenerated(...)]ุชุญุฏูŠุฏ ูƒูŠู ุชุชูˆู„ุฏ ุงู„ู‚ูŠู…ุฉ (Identity, Computed, None)Schema
[NotMapped]ุชุฌุงู‡ู„ ุงู„ู€ property ุฏูŠ ููŠ ุงู„ู€ MappingSchema

ุฅูŠู‡ ุงู„ู„ูŠ ู‡ูŠุญุตู„ ู„ูˆ ุนู…ู„ู†ุง Add-Migration ุฏู„ูˆู‚ุชูŠุŸ

ุจุนุฏ ู…ุง ุนุฏู„ู†ุง ุงู„ู€ Employee class ูˆุถูู†ุง ุงู„ู€ Data Annotations ุฏูŠ ูƒู„ู‡ุง (ุบูŠุฑู†ุง ุงุณู… ุงู„ู€ PKุŒ ุญุฏุฏู†ุง ุงู„ุทูˆู„ ูˆุงู„ู†ูˆุน ู„ู€ columns ุชุงู†ูŠุฉุŒ ุชุฌุงู‡ู„ู†ุง propertyุŒ ุญุทูŠู†ุง rules ู„ู„ู€ validationุŒ ุบูŠุฑู†ุง ุงุณู… ุงู„ู€ Table ูˆุงู„ู€ Schema)ุŒ ู„ูˆ ุฑุญู†ุง ุฏู„ูˆู‚ุชูŠ ุนู„ู‰ ุงู„ู€ Package Manager Console (PM) ูˆูƒุชุจู†ุง:

Add-Migration ApplyEmployeeDataAnnotations

ุงู„ู€ EF Core ู‡ูŠุนู…ู„ ุงู„ุฎุทูˆุงุช ุฏูŠ:

  1. ุงู„ู…ู‚ุงุฑู†ุฉ: ู‡ูŠู‚ุงุฑู† ุงู„ู€ Employee class ุงู„ุญุงู„ูŠ (ุจุงู„ู€ Annotations ุงู„ุฌุฏูŠุฏุฉ) ู…ุน ุขุฎุฑ Snapshot ู…ูˆุฌูˆุฏ ุนู†ุฏูƒ ููŠ ู…ู„ู YourDbContextModelSnapshot.cs (ุงู„ู„ูŠ ูƒุงู† ุจูŠุนูƒุณ ุงู„ุญุงู„ุฉ ุงู„ู‚ุฏูŠู…ุฉ ู‚ุจู„ ุงู„ุชุนุฏูŠู„ุงุช ุฏูŠุŒ ุบุงู„ุจู‹ุง ูƒุงู† ุจูŠุนุชู…ุฏ ุนู„ู‰ ุงู„ู€ Conventions ุจุณ).
  2. ุงูƒุชุดุงู ุงู„ูุฑูˆู‚ุงุช: ู‡ูŠุนุฑู ุฅูŠู‡ ุงู„ู„ูŠ ุงุชุบูŠุฑ ุจุงู„ุธุจุท:
    • ุงุณู… ุงู„ู€ Table ุงุชุบูŠุฑ ูˆุจู‚ู‰ ููŠ schema ู…ุฎุชู„ู.
    • ุงู„ู€ Primary Key ุงุชุบูŠุฑ ุงุณู…ู‡.
    • ุงู„ู€ Name ุจู‚ู‰ Required ูˆุทูˆู„ู‡ ุงุชุบูŠุฑ.
    • ู†ูˆุน ุงู„ู€ Salary ุงุชุบูŠุฑ.
    • ุงู„ู€ FullInfo ุงู„ู…ูุฑูˆุถ ูŠุชุฌุงู‡ู„ู‡ุง.
    • (ุงู„ู€ Annotations ุจุชุงุนุฉ ุงู„ู€ Validation ุฒูŠ [Range] ุบุงู„ุจู‹ุง ู…ุด ู‡ุชุธู‡ุฑ ูƒุชุบูŠูŠุฑ ููŠ ุงู„ู€ Schema ู†ูุณู‡ุŒ ู„ูƒู† ุงู„ู€ EF Core ู…ู…ูƒู† ูŠุณุฌู„ู‡ุง ูƒู€ Metadata).
  3. ุฅู†ุดุงุก ุงู„ู€ Migration File: ู‡ูŠุนู…ู„ ู…ู„ู migration ุฌุฏูŠุฏ (..._ApplyEmployeeDataAnnotations.cs).
    • ุฌูˆู‡ ุงู„ู€ Up() method ู‡ุชู„ุงู‚ูŠ ูƒูˆุฏ C# ุจูŠู†ุงุฏูŠ ุนู„ู‰ MigrationBuilder ุนุดุงู† ูŠุนู…ู„ ุงู„ุชุนุฏูŠู„ุงุช ุฏูŠ ููŠ ุงู„ุฏุงุชุงุจูŠุฒ. ู…ู…ูƒู† ุชู„ุงู‚ูŠ ุฃูˆุงู…ุฑ ุฒูŠ:
      • ุงู„ู€ migrationBuilder.EnsureSchema(name: "hr"); (ู„ูˆ ุงู„ู€ schema ู…ุด ู…ูˆุฌูˆุฏ)
      • ุงู„ู€ migrationBuilder.RenameTable(...) ุฃูˆ migrationBuilder.DropTable(...) ูˆ migrationBuilder.CreateTable(...) (ุญุณุจ ุฅุฒุงูŠ ู‡ูŠู†ู‚ู„ ุงู„ู€ table ู„ู„ู€ schema ุงู„ุฌุฏูŠุฏ ูˆูŠุบูŠุฑ ุงุณู…ู‡).
      • ุงู„ู€ migrationBuilder.RenameColumn(...) ุฃูˆ migrationBuilder.DropPrimaryKey(...) ูˆ migrationBuilder.AddPrimaryKey(...) ุนุดุงู† ูŠุบูŠุฑ ุงู„ู€ PK.
      • ุงู„ู€ migrationBuilder.AlterColumn(...) ูƒุฐุง ู…ุฑุฉ ุนุดุงู† ูŠุบูŠุฑ ู†ูˆุน Salary ูˆูŠุบูŠุฑ ุทูˆู„ ูˆู†ูˆุน Name ูˆูŠุฎู„ูŠู‡ NOT NULL.
    • ุงู„ู€ Down() method ู‡ูŠุจู‚ู‰ ููŠู‡ุง ุงู„ุฃูˆุงู…ุฑ ุงู„ุนูƒุณูŠุฉ ุนุดุงู† ู„ูˆ ุญุจูŠุช ุชุนู…ู„ Rollback.
  4. ุชุญุฏูŠุซ ุงู„ู€ Snapshot: ู…ู„ู ุงู„ู€ YourDbContextModelSnapshot.cs ู‡ูŠุชุนุฏู„ ุนุดุงู† ูŠุนูƒุณ ุงู„ุดูƒู„ ุงู„ุฌุฏูŠุฏ ู„ู„ู€ Employee model ุจูƒู„ ุชูุงุตูŠู„ู‡ ุงู„ุฌุฏูŠุฏุฉ ุงู„ู„ูŠ ุฌุงูŠุฉ ู…ู† ุงู„ู€ Annotations.

ูˆุจุนุฏ ู…ุง ุงู„ู€ Migration ุฏูŠ ุชุชุนู…ู„ุŒ ู„ูˆ ู†ูุฐุช Update-Database ููŠ ุงู„ู€ PMุŒ ูƒู„ ุงู„ุชุบูŠูŠุฑุงุช ุฏูŠ ู‡ุชุชุทุจู‚ ุนู„ู‰ ุงู„ุฏุงุชุงุจูŠุฒ ุจุชุงุนุชูƒ.

ุงู„ุฎู„ุงุตุฉ ู„ู„ุทุฑูŠู‚ุฉ ุงู„ุชุงู†ูŠุฉ: ุงู„ู€ Data Annotations ุจุชุฏูŠู†ุง ุชุญูƒู… ุฃูƒุจุฑ ุจูƒุชูŠุฑ ู…ู† ุงู„ู€ ConventionsุŒ ูˆุจุชุฎู„ูŠู†ุง ู†ู‚ุฏุฑ ู†ุนู…ู„ mapping ูˆ validation ููŠ ู†ูุณ ุงู„ูˆู‚ุช ุจูƒุชุงุจุฉ attributes ุจุณูŠุทุฉ ููˆู‚ ุงู„ู€ model classes. ุฏูŠ ุทุฑูŠู‚ุฉ ุดุงุฆุนุฉ ุฌุฏู‹ุง ูˆู…ููŠุฏุฉุŒ ุฎุตูˆุตู‹ุง ููŠ ASP.NET Core. ุจุณ ุนูŠุจู‡ุง ุฅู†ู‡ุง ู…ู…ูƒู† ุชุฎู„ูŠ ุงู„ู€ POCO classes ุจุชุงุนุชู†ุง ููŠู‡ุง ุชูุงุตูŠู„ ู„ูŠู‡ุง ุนู„ุงู‚ุฉ ุจุงู„ู€ Infrastructure (ุงู„ุฏุงุชุงุจูŠุฒ ุฃูˆ ุงู„ู€ validation)ุŒ ูˆุฏู‡ ู…ู…ูƒู† ู†ุงุณ ุชุนุชุจุฑู‡ ุจูŠุฎุงู„ู ู…ุจุฏุฃ Separation of Concerns. ุนุดุงู† ูƒุฏู‡ ููŠู‡ ุทุฑูŠู‚ุฉ ุชุงู„ุชุฉ (Fluent API) ุจุชูุตู„ ุงู„ู€ configuration ุฏู‡ ุชู…ุงู…ู‹ุง ููŠ ู…ูƒุงู† ู„ูˆุญุฏู‡.

3. Fluent API (ุงู„ุชุญูƒู… ุงู„ูƒุงู…ู„)

ุฏูŠ ุงู„ุทุฑูŠู‚ุฉ ุงู„ุฃู‚ูˆู‰ ูˆุงู„ุฃูƒุซุฑ ู…ุฑูˆู†ุฉ ููŠ ุงู„ู€ Mapping. ูƒู„ู…ุฉ Fluent ู‡ู†ุง ู…ุนู†ุงู‡ุง ุฅู† ุงู„ูƒูˆุฏ ุงู„ู„ูŠ ุจู†ูƒุชุจู‡ ุจูŠูƒูˆู† ุณู„ุณ ูˆุดุจู‡ ุงู„ุฌู…ู„ ุงู„ุฅู†ุฌู„ูŠุฒูŠุฉ ุดูˆูŠุฉ.

  • ุฅู…ุชู‰ ุจู†ุณุชุฎุฏู…ู‡ุงุŸ ุจู†ู„ุฌุฃ ู„ู„ู€ Fluent API ุบุงู„ุจู‹ุง ููŠ ุณูŠู†ุงุฑูŠูˆู‡ูŠู† ุฃุณุงุณูŠูŠู†:

    1. ุญุงุฌุงุช ู…ูŠู†ูุนุด ุชุชุนู…ู„ ุบูŠุฑ ุจูŠู‡ุง: ู„ูˆ ุนุงูŠุฒ ุชุนู…ู„ configurations ู…ุนู‚ุฏุฉ ุดูˆูŠุฉ ุฃูˆ ุญุงุฌุงุช ู…ุด ู…ุฏุนูˆู…ุฉ ููŠ ุงู„ู€ Conventions ุฃูˆ ุงู„ู€ Data Annotations. ุฃู…ุซู„ุฉ:
      • ุงู„ู€ Composite Primary Key: ู„ูˆ ุงู„ู€ Primary Key ุจุชุงุนูƒ ู…ูƒูˆู† ู…ู† ุฃูƒุชุฑ ู…ู† column ูˆุงุญุฏ.
      • ุชุบูŠูŠุฑ ุงู„ู€ Increment Step: ู„ูˆ ุนุงูŠุฒ ุงู„ู€ Identity column ูŠุฒูŠุฏ ุจู…ู‚ุฏุงุฑ ู…ุฎุชู„ู ุนู† 1 (ู…ุซู„ู‹ุง ูŠุฒูŠุฏ 5 ูƒู„ ู…ุฑุฉ).
      • ุชุญุฏูŠุฏ Default Value ุฏูŠู†ุงู…ูŠูƒูŠ: ู„ูˆ ุนุงูŠุฒ ุชุญุท ู‚ูŠู…ุฉ ุงูุชุฑุงุถูŠุฉ ู„ู€ column ุจุณ ุงู„ู‚ูŠู…ุฉ ุฏูŠ ุจุชุชุญุณุจ ู…ู† ุงู„ุฏุงุชุงุจูŠุฒ ู†ูุณู‡ุง (ุฒูŠ ุชุงุฑูŠุฎ ูˆูˆู‚ุช ุงู„ุฅุถุงูุฉ ุงู„ูุนู„ูŠ).
      • ุนู…ู„ Indexes ู…ุนู‚ุฏุฉ: ู„ูˆ ุนุงูŠุฒ ุชุนู…ู„ index ุนู„ู‰ ุฃูƒุชุฑ ู…ู† column ุฃูˆ index ู…ู† ู†ูˆุน ุฎุงุต.
      • ุชุญุฏูŠุฏ ุชูุงุตูŠู„ ุฏู‚ูŠู‚ุฉ ููŠ ุงู„ุนู„ุงู‚ุงุช (Relationships): ุฒูŠ ุชุญุฏูŠุฏ ุฃุณู…ุงุก ุงู„ู€ Foreign Keys ุฃูˆ ุณู„ูˆูƒ ุงู„ุญุฐู (Cascade Delete) ุจุดูƒู„ ุฏู‚ูŠู‚ ุฌุฏู‹ุง.
    2. ู„ูˆ ู…ุด ู…ุนุงูƒ ุงู„ู€ Source Code: ุชุฎูŠู„ ุฅู† ุงู„ู€ Entity Class ุจุชุงุนูƒ (ุฒูŠ Employee ุฃูˆ Department) ุฌุงูŠู„ูƒ ู…ู† library ุชุงู†ูŠุฉ ุฃูˆ ู…ู† ุชูŠู… ุชุงู†ูŠุŒ ูˆุฅู†ุช ู…ุด ู…ุนุงูƒ ุงู„ูƒูˆุฏ ุงู„ู…ุตุฏุฑูŠ (Source Code) ุจุชุงุนู‡ุŒ ู…ุนุงูƒ ุจุณ ุงู„ู…ู„ู ุงู„ู€ compiled (ุฒูŠ ุงู„ู€ .dll ุงู„ู„ูŠ ููŠู‡ ุงู„ู€ IL code). ููŠ ุงู„ุญุงู„ุฉ ุฏูŠุŒ ุฅู†ุช ู…ุด ู‡ุชู‚ุฏุฑ ุชูุชุญ ุงู„ูƒู„ุงุณ ูˆุชุถูŠู ุนู„ูŠู‡ Data Annotations. ุงู„ุญู„ ู‡ู†ุง ู‡ูˆ ุฅู†ูƒ ุชุณุชุฎุฏู… Fluent API ุนุดุงู† ุชุนู…ู„ ูƒู„ ุงู„ู€ configuration ูˆุงู„ู€ mapping ุงู„ู…ุทู„ูˆุจ ู„ู„ูƒู„ุงุณ ุฏู‡ ู…ู† ู…ูƒุงู† ุฎุงุฑุฌูŠ (ุงู„ู„ูŠ ู‡ูˆ ุงู„ู€ DbContext).
  • ุจู†ูƒุชุจู‡ุง ููŠู†ุŸ ุงู„ู€ Configurations ุจุชุงุนุฉ ุงู„ู€ Fluent API ุจุชุชูƒุชุจ ุฌูˆู‡ ุงู„ู€ DbContext ุจุชุงุนู†ุง. ุจู†ุนู…ู„ override ู„ู€ method ู…ู‡ู…ุฉ ุฌุฏู‹ุง ุงุณู…ู‡ุง OnModelCreating. ุงู„ู€ Method ุฏูŠ ุงู„ู€ EF Core ุจูŠู†ุงุฏูŠ ุนู„ูŠู‡ุง ู…ุฑุฉ ูˆุงุญุฏุฉ ู„ู…ุง ูŠุฌูŠ ูŠุจู†ูŠ ุงู„ู€ model ุจุชุงุนู‡ ููŠ ุงู„ุฐุงูƒุฑุฉ.

// Inside your DbContext class (e.g., CompanyDbContext)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // --- Fluent API Configurations Go Here ---
 
    // Example: Set a default value for an 'Address' property in Employee
    // Assuming Employee class has an Address property now
    modelBuilder.Entity<Employee>() // Start configuring the Employee entity
        .Property(e => e.Address)   // Select the Address property using Lambda (BEST WAY)
        .HasDefaultValue("Cairo");  // Set its default value in the database
 
    // Example using nameof (Second best)
    // modelBuilder.Entity<Employee>()
    //     .Property(nameof(Employee.Address))
    //     .HasDefaultValue("Cairo");
 
    // Example using string (NOT Recommended - no compile-time check)
    // modelBuilder.Entity<Employee>()
    // 	.Property("Address") // Prone to typos if property name changes
    // 	.HasDefaultValue("Cairo");
 
 
    // --- IMPORTANT: Call the base method at the end ---
    base.OnModelCreating(modelBuilder);
}
  • ุดุฑุญ Property() Method:
    • ุงู„ู€ Method ุฏูŠ ุงู„ู„ูŠ ุจู†ุณุชุฎุฏู…ู‡ุง ุนุดุงู† ู†ุฎุชุงุฑ property ู…ุนูŠู†ุฉ ุฌูˆู‡ ุงู„ู€ Entity ูˆู†ุจุฏุฃ ู†ุนู…ู„ ู„ู‡ุง configuration. ุจุชุงุฎุฏ ุงุณู… ุงู„ู€ property ูƒู€ input.
    • ุงู„ุทุฑูŠู‚ุฉ ุงู„ุฃูˆู„ู‰ (String - ู…ุด ูƒูˆูŠุณุฉ): ุงู†ูƒ ุชูƒุชุจ ุงุณู… ุงู„ู€ property ูƒู€ string ("Address"). ู…ุดูƒู„ุชู‡ุง ุฅู† ู„ูˆ ุบูŠุฑุช ุงุณู… ุงู„ู€ property ููŠ ุงู„ูƒู„ุงุณ ุงู„ุฃุตู„ูŠ ุฃูˆ ูƒุชุจุช ุงู„ุงุณู… ุบู„ุท ู‡ู†ุงุŒ ุงู„ูƒูˆุฏ ู‡ูŠุนู…ู„ compile ุนุงุฏูŠุŒ ูˆู…ุด ู‡ุชูƒุชุดู ุงู„ู…ุดูƒู„ุฉ ุบูŠุฑ ูˆู‚ุช ุงู„ู€ runtime (ู„ู…ุง ุชูŠุฌูŠ ุชุดุบู„ ุงู„ุจุฑู†ุงู…ุฌ ุฃูˆ ุชุนู…ู„ migration).
    • ุงู„ุทุฑูŠู‚ุฉ ุงู„ุชุงู†ูŠุฉ (nameof - ุฃุญุณู†): ุชุณุชุฎุฏู… nameof(Employee.Address). ุฏูŠ ุฃุญุณู† ู…ู† ุงู„ู€ string ู„ุฃู† ู„ูˆ ุงุณู… ุงู„ู€ property ุงุชุบูŠุฑุŒ ุงู„ูƒูˆุฏ ุฏู‡ ู…ุด ู‡ูŠุนู…ู„ compile ูˆู‡ุชุนุฑู ุงู„ุบู„ุท ุจุฏุฑูŠ.
    • ุงู„ุทุฑูŠู‚ุฉ ุงู„ุชุงู„ุชุฉ (Lambda Expression - ุงู„ุฃูุถู„ ูˆุงู„ุฃุถู…ู†): ุฅู†ูƒ ุชุณุชุฎุฏู… Lambda expression ุฒูŠ e => e.Address. ุฏูŠ ุฃุญุณู† ูˆุฃุถู…ู† ุทุฑูŠู‚ุฉ ู„ุฃู†ู‡ุง ุจุชุณุชุฎุฏู… Strongly-typed AccessุŒ ูŠุนู†ูŠ ุงู„ู€ compiler ุจูŠุชุฃูƒุฏ ุฅู† ุงู„ู€ property ุฏูŠ ู…ูˆุฌูˆุฏุฉ ูุนู„ู‹ุง ููŠ ุงู„ู€ Employee class ูˆู‚ุช ุงู„ู€ compile. ูˆูƒู…ุงู† ุจุชุฏุนู… ุงู„ู€ Refactoring (ู„ูˆ ุบูŠุฑุช ุงุณู… ุงู„ู€ property ุจุงุณุชุฎุฏุงู… ุฃุฏูˆุงุช ุงู„ู€ IDEุŒ ู‡ุชุชุบูŠุฑ ู‡ู†ุง ูƒู…ุงู†).

ุฅูŠู‡ ุงู„ุญุงุฌุงุช ุงู„ู„ูŠ ู…ู…ูƒู† ุฃุนู…ู„ู‡ุง ุจุงู„ู€ Fluent APIุŸ (ุฃู…ุซู„ุฉ ุจุณูŠุทุฉ)

ุงู„ู€ Fluent API ุจุชุบุทูŠ ุชู‚ุฑูŠุจู‹ุง ูƒู„ ุญุงุฌุฉ ู…ู…ูƒู† ุชุญุชุงุฌู‡ุง ููŠ ุงู„ู€ Mapping:

  • ุชุญุฏูŠุฏ ุงู„ู€ Table ูˆุงู„ู€ Schema:
    modelBuilder.Entity<Employee>().ToTable("EmployeesInfo", schema: "hr");
  • ุชุญุฏูŠุฏ ุงู„ู€ Primary Key:
    modelBuilder.Entity<Employee>().HasKey(e => e.EmpId); // Single PK
    modelBuilder.Entity<OrderLine>().HasKey(ol => new { ol.OrderId, ol.ProductId }); // Composite PK
  • ุชุญุฏูŠุฏ ุงู„ู€ Column:
    modelBuilder.Entity<Employee>()
        .Property(e => e.Name)
        .HasColumnName("EmployeeFullName") // Change column name
        .HasColumnType("varchar(150)")    // Change data type and length
        .IsRequired();                     // Make it NOT NULL
  • ุงู„ู€ Default Values:
    modelBuilder.Entity<Employee>()
        .Property(e => e.Status)
        .HasDefaultValue("Active"); // Default string value
  • ุงู„ู€ Computed Columns (ู‚ูŠู… ู…ุญุณูˆุจุฉ ููŠ ุงู„ุฏุงุชุงุจูŠุฒ):
    modelBuilder.Entity<Employee>()
        .Property(e => e.FullName) // Assume FullName is string in C#
        .HasComputedColumnSql("[LastName] + ', ' + [FirstName]"); // SQL expression
    • ู…ู‡ู…: ุฒูŠ ู…ุง ู‡ู†ุดูˆูุŒ ู„ูˆ ุนุงูŠุฒ ู‚ูŠู…ุฉ ุจุชุชุบูŠุฑ ู…ุน ุงู„ูˆู‚ุช ุฒูŠ ุชุงุฑูŠุฎ ุงู„ุฅู†ุดุงุกุŒ ุงุณุชุฎุฏู… HasComputedColumnSql ู…ุน ุฏุงู„ุฉ ุงู„ุฏุงุชุงุจูŠุฒ (ุฒูŠ GETDATE() ููŠ SQL Server) ุจุฏู„ HasDefaultValue(DateTime.Now).
  • ุงู„ู€ Identity / Auto-increment:
    modelBuilder.Entity<Employee>()
        .Property(e => e.EmpId)
        .UseIdentityColumn(seed: 100, increment: 5); // Start at 100, increment by 5
  • ุชุฌุงู‡ู„ Property (ุฒูŠ [NotMapped]):
    modelBuilder.Entity<Employee>().Ignore(e => e.TemporaryNotes);
  • ุนู…ู„ Index:
    modelBuilder.Entity<Employee>()
        .HasIndex(e => e.Email) // Index on Email
        .IsUnique();           // Make it a unique index
     
    modelBuilder.Entity<Employee>()
        .HasIndex(e => new { e.LastName, e.FirstName }); // Index on multiple columns
  • ุชุญุฏูŠุฏ ุงู„ุนู„ุงู‚ุงุช (Relationships): (ูˆุฏูŠ ู„ูŠู‡ุง ุชูุงุตูŠู„ ูƒุชูŠุฑ ุจุณ ูƒู…ุซุงู„ ุจุณูŠุท)
    // One-to-Many: Department has many Employees
    modelBuilder.Entity<Employee>()
        .HasOne(e => e.Department) // Navigation property in Employee
        .WithMany(d => d.Employees) // Navigation property in Department
        .HasForeignKey(e => e.DeptId) // Foreign key property in Employee
        .OnDelete(DeleteBehavior.Restrict); // Define delete behavior

ู…ุซุงู„ ุชูุตูŠู„ูŠ: Mapping ู„ูƒู„ุงุณ Department (ุจุฏูˆู† Source Code)

ู‡ู†ุฑุฌุน ู„ุณูŠู†ุงุฑูŠูˆ ุฅู†ู†ุง ุนู†ุฏู†ุง Class ุงุณู…ู‡ Department ุฌุงูŠ ู…ู† library ุชุงู†ูŠุฉุŒ ูˆุฅุญู†ุง ู…ุนู†ุฏู†ุงุด ุงู„ูƒูˆุฏ ุจุชุงุนู‡ ุนุดุงู† ู†ุญุท ุนู„ูŠู‡ Annotations. ู‡ู†ูุชุฑุถ ุฅู† ุดูƒู„ ุงู„ูƒู„ุงุณ ุฏู‡ ูƒุงู† ุญุงุฌุฉ ุฒูŠ ูƒุฏู‡ (ุฅุญู†ุง ู…ุด ุจู†ูƒุชุจ ุงู„ูƒู„ุงุณ ุฏู‡ุŒ ู‡ูˆ ุฌุงูŠ ุฌุงู‡ุฒ):

// Imagine this class comes from a compiled library (DLL)
// We cannot modify it directly
public class Department
{
    public int DeptId { get; set; } // Needs to be PK, needs Identity with custom seed/step
    public string Name { get; set; } // Needs to be required, varchar(50), different column name, default value
    public DateTime DateOfCreation { get; set; } // Needs DB default GETDATE()
}

ุฏู„ูˆู‚ุชูŠุŒ ููŠ ุงู„ู€ DbContext ุจุชุงุนู†ุงุŒ ู‡ู†ุนู…ู„ ุงู„ุขุชูŠ:

  1. ู†ุถูŠู ู„ู‡ DbSet: (ุญุชู‰ ู„ูˆ ุฌุงูŠ ู…ู† libraryุŒ ู„ุงุฒู… ู†ุนุฑู ุงู„ู€ DbContext ุฅู†ู†ุง ุนุงูŠุฒูŠู† ู†ุชุนุงู…ู„ ู…ุนุงู‡)

    // Inside CompanyDbContext
    public DbSet<Department> Departments { get; set; }
  2. ู†ุนู…ู„ ู„ู‡ Configuration ููŠ OnModelCreating ุจุงุณุชุฎุฏุงู… Fluent API:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // --- Configure Employee (as before maybe) ---
        // modelBuilder.Entity<Employee>()...
     
        // --- Configure Department using Fluent API ---
        modelBuilder.Entity<Department>(E => // Use lambda for cleaner syntax
        {
            // Map to specific Table name and Schema
            E.ToTable("Departments", "hr"); // Map to hr.Departments table
     
            // Define the Primary Key (since it's not named 'Id' or 'DepartmentId')
            E.HasKey(D => D.DeptId);
     
            // Configure the Primary Key property to be Identity with custom seed and increment
            E.Property(D => D.DeptId)
                .UseIdentityColumn(seed: 10, increment: 10); // Start at 10, increment by 10
     
            // Configure the 'Name' property
            E.Property(D => D.Name)
                .IsRequired(true)                  // Make it NOT NULL
                .HasColumnType("varchar(50)")      // Set DB type and length
                .HasColumnName("DepartmentName")   // Change column name in DB
                .HasMaxLength(50)                  // Also specifies max length (can be redundant with TypeName)
                // .HasAnnotation("SomeMetadata", "Value") // Way to add custom metadata if needed
                .HasDefaultValue("Default Dept");  // Set a static default value
     
            // Configure the 'DateOfCreation' property
            E.Property(D => D.DateOfCreation)
                // WRONG WAY for dynamic default: .HasDefaultValue(DateTime.Now);
                // This captures the time when the MIGRATION is created, not when the row is inserted!
     
                // RIGHT WAY: Use a database function for the default value
                .HasComputedColumnSql("GETDATE()"); // For SQL Server, generates default value on insert
                // Or alternatively for default constraint: .HasDefaultValueSql("GETDATE()");
        });
     
        // --- Call base method ---
        base.OnModelCreating(modelBuilder);
    }
     
  • ุดุฑุญ ุณุฑูŠุน ู„ู„ู†ู‚ุท ุงู„ู…ู‡ู…ุฉ ููŠ ุงู„ู…ุซุงู„ ุฏู‡:
    • ุงุณุชุฎุฏู…ู†ุง Entity<Department>(E => { ... }) ุนุดุงู† ู†ู„ู… ุงู„ู€ configurations ุจุชุงุนุฉ Department ู…ุน ุจุนุถุŒ ูˆุฏูŠ ุทุฑูŠู‚ุฉ ุฃุฌุฏุฏ ูˆุฃู†ุถู (ู…ูˆุฌูˆุฏุฉ ู…ู† EF Core 3.1 ุชู‚ุฑูŠุจู‹ุง).
    • ุงู„ู€ ToTable() ุญุฏุฏุช ุงุณู… ุงู„ู€ Table ูˆุงู„ู€ Schema.
    • ุงู„ู€ HasKey() ูƒุงู†ุช ุถุฑูˆุฑูŠุฉ ู„ุฃู† ุงุณู… ุงู„ู€ property (DeptId) ู…ุด ู…ุงุดูŠ ู…ุน ุงู„ู€ Convention ุจุชุงุนุฉ ุงู„ู€ PK.
    • ุงู„ู€ UseIdentityColumn(10, 10) ุฏูŠ ู…ู‚ุฏุฑู†ุงุด ู†ุนู…ู„ู‡ุง ุจุงู„ู€ AnnotationุŒ ู‡ู†ุง ุจู†ุญุฏุฏ ุจุฏุงูŠุฉ ุงู„ุนุฏ (10) ูˆู…ู‚ุฏุงุฑ ุงู„ุฒูŠุงุฏุฉ (10).
    • ููŠ Property(D => D.Name) ุดูˆูู†ุง ุฅุฒุงูŠ ู…ู…ูƒู† ู†ุนู…ู„ ูƒุฐุง configuration ูˆุฑุง ุจุนุถ ู„ู†ูุณ ุงู„ู€ property.
    • ููŠ Property(D => D.DateOfCreation)ุŒ ุงู„ู†ู‚ุทุฉ ุจุชุงุนุฉ HasComputedColumnSql("GETDATE()") ุฃูˆ HasDefaultValueSql("GETDATE()") ู…ู‡ู…ุฉ ุฌุฏู‹ุง. ู„ูˆ ูƒู†ุช ุงุณุชุฎุฏู…ุช HasDefaultValue(DateTime.Now)ุŒ ูƒุงู†ุช ู‚ูŠู…ุฉ DateTime.Now ุงู„ู„ูŠ ู‡ุชุชู†ูุฐ ูˆู‚ุช ุนู…ู„ ุงู„ู€ Migration ู‡ูŠ ุงู„ู„ูŠ ู‡ุชุชุญุท ูƒู‚ูŠู…ุฉ ุงูุชุฑุงุถูŠุฉ ุซุงุจุชุฉ ููŠ ุงู„ุฏุงุชุงุจูŠุฒุŒ ูˆุฏู‡ ู…ุด ุตุญ ู„ูˆ ุนุงูŠุฒ ุงู„ุชุงุฑูŠุฎ ุงู„ูุนู„ูŠ ู„ุฅุถุงูุฉ ุงู„ู€ row. ุงุณุชุฎุฏุงู… ุฏุงู„ุฉ ุงู„ุฏุงุชุงุจูŠุฒ ุฒูŠ GETDATE() ุจูŠุถู…ู† ุฅู† ุงู„ู‚ูŠู…ุฉ ุชุชุญุณุจ ุตุญ ูˆู‚ุช ุงู„ู€ INSERT.

4. Configuration Classes (Organize Fluent API)

ุงู„ู€ Fluent API ู‚ูˆูŠุฉ ุฌุฏู‹ุงุŒ ุจุณ ููŠู‡ ู…ุดูƒู„ุฉ ู…ู…ูƒู† ุชุธู‡ุฑ: ู„ูˆ ุงู„ุฃุจู„ูƒูŠุดู† ุจุชุงุนูƒ ูƒุจูŠุฑ ูˆููŠู‡ Entities ูƒุชูŠุฑุŒ ุงู„ู€ OnModelCreating method ุฏูŠ ู‡ุชุจู‚ู‰ ุทูˆูŠู„ุฉ ุฌุฏู‹ุง ูˆู…ู„ูŠุงู†ุฉ configurations ูˆู…ู…ูƒู† ุชุจู‚ู‰ ุตุนุจุฉ ููŠ ุงู„ู‚ุฑุงูŠุฉ ูˆุงู„ุตูŠุงู†ุฉ.

ู‡ู†ุง ุชูŠุฌูŠ ุงู„ุทุฑูŠู‚ุฉ ุงู„ุฑุงุจุนุฉุŒ ูˆู‡ูŠ ููŠ ุงู„ุญู‚ูŠู‚ุฉ ู…ุด ุทุฑูŠู‚ุฉ mapping ุฌุฏูŠุฏุฉุŒ ู‚ุฏ ู…ุง ู‡ูŠ ุทุฑูŠู‚ุฉ ุชู†ุธูŠู…ูŠุฉ ู„ู„ุทุฑูŠู‚ุฉ ุงู„ุชุงู„ุชุฉ (Fluent API).

  • ุงู„ููƒุฑุฉ: ุจุฏู„ ู…ุง ุชูƒุชุจ ูƒู„ ุงู„ู€ Fluent API configurations ุจุชุงุนุฉ ูƒู„ ุงู„ู€ Entities ุฌูˆู‡ OnModelCreatingุŒ ู‡ุชุนู…ู„ Class ู…ู†ูุตู„ ู„ูƒู„ Entity ุนุดุงู† ุชุญุท ุฌูˆุงู‡ ุงู„ู€ configurations ุจุชุงุนุชู‡.
  • ุงู„ุฎุทูˆุงุช:
    1. ุนู…ู„ Folder: ู†ุนู…ู„ folder ุฌุฏูŠุฏ ููŠ ุงู„ู€ Project ุนุดุงู† ู†ู†ุธู… ุงู„ู€ configuration classes ุฏูŠุŒ ู†ุณู…ูŠู‡ ู…ุซู„ู‹ุง Configurations ุฃูˆ EntityConfigurations.
    2. ุนู…ู„ Class ู„ูƒู„ Entity: ู„ูƒู„ Entity ุนุงูŠุฒ ุชุนู…ู„ู‡ุง configuration (ุฒูŠ Employee, Department)ุŒ ู‡ุชุนู…ู„ Class ุฌุฏูŠุฏ ุฌูˆู‡ ุงู„ู€ folder ุฏู‡. ุงุณู… ุงู„ู€ Class ุฏู‡ ุนุงุฏุฉ ุจูŠูƒูˆู† EntityNameConfiguration (ู…ุซู„ู‹ุง EmployeeConfiguration, DepartmentConfiguration).
    3. ุนู…ู„ Implement ู„ู„ู€ Interface: ูƒู„ configuration class ู…ู† ุฏูˆู„ ู„ุงุฒู… ูŠุนู…ู„ implement ู„ู€ interface ู…ู‡ู… ุงุณู…ู‡ IEntityTypeConfiguration<TEntity>. ุงู„ู€ TEntity ู‡ู†ุง ู‡ูˆ ุงุณู… ุงู„ู€ Entity class ุงู„ู„ูŠ ุงู„ู€ configuration class ุฏู‡ ู…ุณุฆูˆู„ ุนู†ู‡.
      • ุงู„ู€ Interface ุฏู‡ ููŠู‡ method ูˆุงุญุฏุฉ ุจุณ ุงุณู…ู‡ุง Configure. ุฌูˆู‡ ุงู„ู€ Configure ุฏูŠ ุจู‚ู‰ ู‡ุชุญุท ูƒู„ ูƒูˆุฏ ุงู„ู€ Fluent API ุงู„ู„ูŠ ูƒู†ุช ู‡ุชูƒุชุจู‡ ููŠ OnModelCreating ุจุณ ู„ู„ู€ Entity ุฏูŠ ุจุณ.

ู…ุซุงู„: ุนู…ู„ DepartmentConfiguration

// File: Configurations/DepartmentConfiguration.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
// Assuming Department class is accessible here
 
internal class DepartmentConfiguration : IEntityTypeConfiguration<Department>
{
    public void Configure(EntityTypeBuilder<Department> builder) // Note: It's EntityTypeBuilder here, not ModelBuilder
    {
        // --- All Fluent API for Department goes here ---
        // Move the code from OnModelCreating here, replacing 'E.' with 'builder.'
 
        builder.ToTable("Departments", "hr");
 
        builder.HasKey(D => D.DeptId);
 
        builder.Property(D => D.DeptId)
            .UseIdentityColumn(seed: 10, increment: 10);
 
        builder.Property(D => D.Name)
            .IsRequired(true)
            .HasColumnType("varchar(50)")
            .HasColumnName("DepartmentName")
            .HasMaxLength(50)
            .HasDefaultValue("Default Dept");
 
        builder.Property(D => D.DateOfCreation)
            .HasComputedColumnSql("GETDATE()");
            // .HasDefaultValueSql("GETDATE()"); // Alternative
    }
}

ุฅุฒุงูŠ ุงู„ู€ DbContext ูŠุนุฑู ุจุงู„ู€ Configuration Classes ุฏูŠุŸ

ุจุนุฏ ู…ุง ุนู…ู„ุช ุงู„ู€ Configuration Class (ุฒูŠ DepartmentConfiguration)ุŒ ู„ุงุฒู… ุชุฑุฌุน ู„ู„ู€ DbContext ูˆุชู‚ูˆู„ู‡ ูŠุณุชุฎุฏู… ุงู„ู€ configuration ุฏูŠ. ุจู†ุนู…ู„ ุฏู‡ ุฌูˆู‡ OnModelCreating ุจุฑุถู‡ุŒ ุจุณ ุจุฏู„ ู…ุง ู†ูƒุชุจ ุงู„ูƒูˆุฏ ูƒู„ู‡ุŒ ู‡ู†ุงุฏูŠ ุนู„ู‰ ุงู„ู€ configuration class.

  • ุงู„ุทุฑูŠู‚ุฉ ุงู„ู…ุจุงุดุฑุฉ (ู„ูƒู„ ูƒู„ุงุณ ู„ูˆุญุฏู‡):

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Apply the Department configuration
        modelBuilder.ApplyConfiguration(new DepartmentConfiguration());
     
        // Apply other configurations if you have them
        // modelBuilder.ApplyConfiguration(new EmployeeConfiguration());
        // ... etc ...
     
        // --- IMPORTANT: Call the base method at the end ---
        base.OnModelCreating(modelBuilder);
    }
    • ุจู†ุณุชุฎุฏู… modelBuilder.ApplyConfiguration() ูˆู†ุฏูŠู‡ุง instance ุฌุฏูŠุฏุฉ ู…ู† ุงู„ู€ configuration class ุจุชุงุนู†ุง.
  • ูุงูŠุฏุฉ base.OnModelCreating(modelBuilder);:

    • ุงู„ุณุทุฑ ุฏู‡ ู…ู‡ู… ุฌุฏู‹ุง ูˆู…ูุฑูˆุถ ู†ุณูŠุจู‡ ููŠ ุงู„ุขุฎุฑ ุบุงู„ุจู‹ุง. ูุงูŠุฏุชู‡ ุฅู†ู‡ ุจูŠุชุฃูƒุฏ ุฅู† ุฃูŠ configurations ุชุงู†ูŠุฉ ุงู„ู€ EF Core ู…ู…ูƒู† ูŠูƒูˆู† ุจูŠุนู…ู„ู‡ุง ู„ูˆุญุฏู‡ (ูƒุฌุฒุก ู…ู† ุงู„ู€ conventions ุจุชุงุนุชู‡ ุฃูˆ ู„ูˆ ุงู„ู€ DbContext ุจุชุงุนูƒ ูˆุงุฑุซ ู…ู† DbContext ุชุงู†ูŠ ููŠู‡ OnModelCreating) ุชุชู†ูุฐ ู‡ูŠ ูƒู…ุงู†. ู„ูˆ ุดูŠู„ุชู‡ุŒ ู…ู…ูƒู† ุจุนุถ ุงู„ุณู„ูˆูƒูŠุงุช ุงู„ุงูุชุฑุงุถูŠุฉ ุฃูˆ ุงู„ูˆุฑุงุซูŠุฉ ู…ุชุดุชุบู„ุด.
  • ุงู„ุทุฑูŠู‚ุฉ ุงู„ุฃูˆุชูˆู…ุงุชูŠูƒูŠุฉ (ุจุงุณุชุฎุฏุงู… Reflection):

    • ู„ูˆ ุนู†ุฏูƒ configuration classes ูƒุชูŠุฑุŒ ุจุฏู„ ู…ุง ุชู‚ุนุฏ ุชุถูŠู ุณุทุฑ ApplyConfiguration ู„ูƒู„ ูˆุงุญุฏ ููŠู‡ู…ุŒ ููŠู‡ ุทุฑูŠู‚ุฉ ุฃุดูŠูƒ ูˆุฃูˆุชูˆู…ุงุชูŠูƒ ุฃูƒุชุฑ ุจุชุณุชุฎุฏู… Reflection. ุงู„ุทุฑูŠู‚ุฉ ุฏูŠ ุจุชุฎู„ูŠ ุงู„ู€ EF Core ูŠุฏูˆุฑ ุจู†ูุณู‡ ุนู„ู‰ ูƒู„ ุงู„ู€ Classes ููŠ ุงู„ู€ Assembly (ุงู„ู€ project) ุจุชุงุนูƒ ุงู„ู„ูŠ ุจุชุนู…ู„ implement ู„ู„ู€ IEntityTypeConfiguration<T> ูˆูŠุฑูˆุญ ุนุงู…ู„ู‡ุง apply ู„ูˆุญุฏู‡.
    • ุงู„ูƒูˆุฏ ุจุชุงุนู‡ุง ุจูŠุจู‚ู‰ ุญุงุฌุฉ ุฒูŠ ูƒุฏู‡:
      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
          // Automatically apply all configurations from the current assembly
          modelBuilder.ApplyConfigurationsFromAssembly(System.Reflection.Assembly.GetExecutingAssembly());
       
          // No need to call ApplyConfiguration for each class manually anymore
       
          // --- IMPORTANT: Call the base method at the end ---
          base.OnModelCreating(modelBuilder);
      }
    • ุงู„ุณุทุฑ ุฏู‡ ูƒุงููŠ ุฅู†ู‡ ูŠู„ุงู‚ูŠ ูˆูŠู†ูุฐ ูƒู„ ุงู„ู€ configuration classes ุงู„ู„ูŠ ููŠ ุงู„ู€ project ุจุชุงุนูƒ. ุฏูŠ ุงู„ุทุฑูŠู‚ุฉ ุงู„ู…ูุถู„ุฉ ููŠ ุงู„ู…ุดุงุฑูŠุน ุงู„ูƒุจูŠุฑุฉ.

ุงู„ุฎุทูˆุฉ ุงู„ุฃุฎูŠุฑุฉ: ุนู…ู„ ุงู„ู€ Migration

ุจุนุฏ ู…ุง ุฎู„ุตุช ูƒู„ ุงู„ู€ configurations ุจุชุงุนุชูƒ ุจุงุณุชุฎุฏุงู… Fluent API (ุณูˆุงุก ูƒุชุจุชู‡ุง ู…ุจุงุดุฑุฉ ููŠ OnModelCreating ุฃูˆ ู†ุธู…ุชู‡ุง ููŠ Configuration Classes)ุŒ ุงู„ุฎุทูˆุฉ ุงู„ุฌุงูŠุฉ ู‡ูŠ ุฅู†ูƒ ุชุนู…ู„ Managing Database Schema with EF Core Migrations ุนุดุงู† ุชุดูˆู ุงู„ุชุบูŠูŠุฑุงุช ุฏูŠ ูˆุชุทุจู‚ู‡ุง ุนู„ู‰ ุงู„ุฏุงุชุงุจูŠุฒ.

  1. ุงูุชุญ ุงู„ู€ Package Manager Console (PM).
  2. ุงูƒุชุจ ุฃู…ุฑ ุงู„ู€ Add-Migration:
    Add-Migration ConfigureDepartmentUsingFluentApi
    (ุฃูˆ ุฃูŠ ุงุณู… ู…ู†ุงุณุจ ูŠูˆุตู ุงู„ุชุบูŠูŠุฑุงุช ุงู„ู„ูŠ ุนู…ู„ุชู‡ุง).
    • ู‡ู†ุง ุงู„ู€ EF Core ู‡ูŠู‚ุฑุฃ ุงู„ู€ configurations ุจุชุงุนุชูƒ (ุจู…ุง ููŠู‡ุง ุงู„ู„ูŠ ุฌุงูŠุฉ ู…ู† ุงู„ู€ Fluent API) ูˆูŠู‚ุงุฑู†ู‡ุง ุจุงู„ู€ Snapshot ุงู„ู‚ุฏูŠู…ุŒ ูˆูŠุนู…ู„ migration file ุฌุฏูŠุฏ ุจุงู„ูุฑู‚. ุงู„ู…ูุฑูˆุถ ุชูุชุญ ุงู„ูุงูŠู„ ุฏู‡ ูˆุชุชุฃูƒุฏ ุฅู† ุงู„ู€ Up() method ููŠู‡ุง ุงู„ุฃูˆุงู…ุฑ ุงู„ู„ูŠ ุฅู†ุช ู…ุชูˆู‚ุนู‡ุง (ุฒูŠ CreateTable ุฃูˆ AlterColumn ุจุงู„ุชูุงุตูŠู„ ุงู„ุฌุฏูŠุฏุฉ).
  3. ุงูƒุชุจ ุฃู…ุฑ ุงู„ู€ Update-Database:
    Update-Database
    • ุฏู‡ ู‡ูŠู†ูุฐ ุงู„ู€ Migration ุงู„ุฌุฏูŠุฏุฉ ุฏูŠ ุนู„ู‰ ุงู„ุฏุงุชุงุจูŠุฒ ุจุชุงุนุชูƒ.

ูˆุจูƒุฏู‡ ุชูƒูˆู† ู‚ุฏุฑุช ุชุนู…ู„ mapping ูˆ configuration ุจุดูƒู„ ุฏู‚ูŠู‚ ูˆู…ูุตู„ ุจุงุณุชุฎุฏุงู… Fluent API ูˆู†ุธู…ุช ุงู„ูƒูˆุฏ ุจุชุงุนูƒ ุจุงุณุชุฎุฏุงู… Configuration Classes. ุฏูŠ ุชุนุชุจุฑ ุงู„ุทุฑูŠู‚ุฉ ุงู„ุฃูƒุซุฑ ุงุญุชุฑุงููŠุฉ ู„ู„ุชุนุงู…ู„ ู…ุน ุงู„ู€ Mapping ููŠ ุงู„ู€ EF Core Code-First ููŠ ุงู„ู…ุดุงุฑูŠุน ุงู„ูƒุจูŠุฑุฉ ูˆุงู„ู…ุนู‚ุฏุฉ.