হ্যালো হাসিব! তুমি ঠিক পথেই এগোচ্ছো। DbContext এবং ConnectionString সেটআপ করার পর ডাটাবেসে ডাটা ইনসার্ট করার জন্য Seed Data যোগ করা খুবই গুরুত্বপূর্ণ একটি ধাপ।

বিশেষ করে যখন তুমি কোনো SaaS প্রোডাক্ট (যেমন তোমার “Chatrabash” প্রজেক্ট) ডেভেলপ করবে, তখন শুরুতেই কিছু ডিফল্ট ডাটা (যেমন: Admin Role, Countries, বা Default Settings) ডাটাবেসে থাকা প্রয়োজন। এই লেকচারটি মূলত সেটাই ফোকাস করেছে।

চলো লেকচারটির একটি কুইক সামারি দেখে নিই।

📝 Lecture Summary at a Glance

  • What is Seed Data: ডাটাবেস টেবিল তৈরি হওয়ার সাথে সাথে সেখানে কিছু প্রাথমিক ডাটা (Initial Data) যোগ করার প্রক্রিয়াকেই Seed Data বলা হয়।
  • How it works: EF Core-এ ModelBuilder এর HasData() মেথড ব্যবহার করে সিড ডাটা ইনজেক্ট করা হয়।
  • Adding Multiple Rows: ম্যানুয়ালি একটা একটা অবজেক্ট তৈরি করার চেয়ে, একটি .json ফাইলে সব ডাটা রেখে, সেটি C# কোডে রিড ও ডিসিরিয়ালাইজ করে HasData()-তে পাস করা অনেক বেশি ইফিশিয়েন্ট।
  • Migration Dependency: এই Seed Data তখনই ডাটাবেসে যাবে, যখন তুমি Migration রান করবে এবং ডাটাবেস আপডেট করবে। (যা পরবর্তী লেকচারে কভার করা হবে)।

🧠 Comprehensive Breakdown & Deep Dive

১. Seed Data কী এবং কেন প্রয়োজন? [Importance: 9/10]

  • The “Why”: যখন তুমি বা তোমার টিম প্রথমবার প্রোজেক্ট রান করবে, তখন ডাটাবেস সম্পূর্ণ ফাঁকা থাকবে। ফাঁকা ডাটাবেস নিয়ে ফ্রন্টএন্ড টিম বা তুমি নিজেও API ঠিকমতো টেস্ট করতে পারবে না। তাই শুরুতেই কিছু ডামি বা প্রয়োজনীয় ডাটা (যেমন: Country List) দিয়ে টেবিল ফিলআপ করে রাখাই হলো Data Seeding।
  • Rule of Thumb: Seed Data শুধুমাত্র ডাটাবেস তৈরির সময় ইনসার্ট হয়। তুমি যদি ডাটাবেস থেকে ম্যানুয়ালি কোনো Seed Data ডিলিট করে দাও, EF Core সেটি আর নিজে থেকে ফিরিয়ে আনবে না (যতক্ষণ না তুমি নতুন মাইগ্রেশন রান করছো)।

২. JSON ফাইল থেকে Data Seeding (Smart Approach) [Importance: 10/10]

  • The “Why”: তুমি চাইলে HasData(new Country { Id = 1, Name = "BD" }) এভাবে একটা একটা করে ১০০টা দেশের নাম কোডে লিখতে পারো। কিন্তু এতে তোমার DbContext ক্লাস বিশাল বড় এবং অপরিষ্কার হয়ে যাবে। এর চেয়ে একটি এক্সটার্নাল .json ফাইলে ডাটাগুলো রেখে, সেটি রিড করা অনেক স্মার্ট এবং ক্লিন অ্যাপ্রোচ।

💻 Code Implementation (.NET 10 / 8 Modern Approach): লেকচারের কোডটি ঠিক আছে, তবে আমরা এটিকে আরেকটু ক্লিন এবং অপটিমাইজ করবো।

ধাপ ১: JSON ফাইল তৈরি করা প্রজেক্টের রুটে (বা SeedData নামে একটি ফোল্ডারে) countries.json তৈরি করো:

[
  {
    "CountryId": "1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p",
    "CountryName": "Bangladesh"
  },
  {
    "CountryId": "2b3c4d5e-6f7g-8h9i-0j1k-2l3m4n5o6p7q",
    "CountryName": "Canada"
  }
]
 

ধাপ ২: DbContext-এ JSON রিড করে Seeding করা PersonsDbContext.cs ফাইলে OnModelCreating মেথডের ভেতরে নিচের কোডটি লিখবে:

using System.Text.Json; // JSON নিয়ে কাজ করার জন্য
 
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
 
    // ১. ফাইলের লোকেশন ঠিক করা (পাথ নিয়ে যেন সমস্যা না হয়)
    string countriesJsonContent = File.ReadAllText("countries.json");
    
    // ২. JSON কে List<Country> তে কনভার্ট করা
    // (C# 11+ এর সুবিধা নিয়ে আমরা null forgiving operator '!' ব্যবহার করছি)
    List<Country> countries = JsonSerializer.Deserialize<List<Country>>(countriesJsonContent)!;
 
    // ৩. প্রতিটি Country অবজেক্ট ডাটাবেসে Seed করা
    foreach (var country in countries)
    {
        modelBuilder.Entity<Country>().HasData(country);
    }
 
    // Persons এর জন্যও একই কাজ (foreign key ঠিক থাকতে হবে)
    string personsJsonContent = File.ReadAllText("persons.json");
    List<Person> persons = JsonSerializer.Deserialize<List<Person>>(personsJsonContent)!;
    
    foreach (var person in persons)
    {
        modelBuilder.Entity<Person>().HasData(person);
    }
}
 

৩. Foreign Key Dependency (গুরুত্বপূর্ণ সতর্কতা) [Importance: 8/10]

  • The “Why”: লেকচারার একটি খুব গুরুত্বপূর্ণ পয়েন্ট বলেছেন। Person টেবিলে যদি CountryId থাকে (Foreign Key হিসেবে), তবে persons.json ফাইলে তুমি যে Country ID গুলো দেবে, সেগুলো অবশ্যই countries.json ফাইলে থাকতে হবে।
  • ভুল হলে কী হবে? যদি কোনো Person-এর Country ID এমন কিছু দাও যা Country টেবিলে নেই, তাহলে যখন তুমি ডাটাবেস আপডেট (Migration) করতে যাবে, তখন SQL Server “Foreign Key Constraint Violation” এরর দিয়ে ক্র্যাশ করবে।

🚀 Modern C# & Architecture Best Practices

১. Separation of Concerns (Extension Method): তোমার প্রজেক্ট বড় হলে OnModelCreating মেথডটি Seed Data-এর কোড দিয়ে ভরে যাবে। এটিকে ক্লিন রাখার জন্য একটি Extension Method তৈরি করা বেস্ট প্র্যাকটিস।

💻 Pro Tip (Clean Architecture Approach): একটি নতুন ক্লাস তৈরি করো ModelBuilderExtensions.cs:

public static class ModelBuilderExtensions
{
    public static void Seed(this ModelBuilder modelBuilder)
    {
        var countriesData = File.ReadAllText("SeedData/countries.json");
        var countries = JsonSerializer.Deserialize<List<Country>>(countriesData)!;
        modelBuilder.Entity<Country>().HasData(countries); 
        // HasData() লিস্টও রিসিভ করতে পারে, foreach লুপ না চালালেও হবে!
    }
}
 

এরপর তোমার DbContext এ শুধু এক লাইন কোড লিখবে:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Seed(); // একদম ক্লিন!
}
 

২. JSON File Properties (For VS Code/Linux): যখন তুমি অ্যাপ্লিকেশনটি রান করবে, তখন countries.json ফাইলটি যেন bin ফোল্ডারে কপি হয়, তা নিশ্চিত করতে হবে। তোমার প্রজেক্টের .csproj ফাইলে নিচের ব্লকটি অ্যাড করে দেবে:

  <ItemGroup>
    <None Update="countries.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="persons.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>
 

এই লেকচারের পর আমাদের সবকিছু রেডি। পরবর্তী লেকচারেই আমরা Migrations রান করে ডাটাবেস তৈরি করবো। তুমি চাইলে পরের ট্রান্সক্রিপ্টটি দিতে পারো!