# מערך שיעור: EF Core — DbContext, DbSet, Migrations📋 מערך מרצה

משך: 4 שעות אקדמיות (180 דקות).

מטרת השיעור: הסטודנטים יריצו שרשרת שלמה מאפס — Docker ל-DB, DbContext, Migrations, ושני endpoints אמיתיים — ולא רק יבינו את הרעיון בתיאוריה.

בסוף השיעור הסטודנטים צריכים: להרים SQL Server בעצמם ב-Docker, להגדיר DbContext עם DbSet, ליצור ולהחיל Migration, ולהריץ API שבאמת קורא/כותב ל-DB דרך שני endpoints (GET/POST).

דגש קריטי: זהו השיעור הכי "ידיים על המקלדת" עד כה ביחידה — כל שלב תלוי בשלב שלפניו (בלי Docker רץ, שום דבר אחר לא יעבוד), ורצוי לעבור אותם ממש לפי הסדר, לא ברצף שקופיות בלבד. קשרו במפורש לסכמה שתוכננה בשיעור הקודם — זו לא סכמה חדשה, זו אותה סכמה, רק ממופה מקוד C#.

---

## מהלך השיעור

| חלק בשיעור | משך | הערות ודגשים |
| --- | --- | --- |
| פתיחה וחיבור | 5 דקות | הזכירו CREATE TABLE ידני מהשיעור הקודם — "יש דרך פשוטה יותר?" |
| NuGet Packages + dotnet-ef | 10 דקות | `dotnet add package` — ספרייה חיצונית, לא מובנית; `dotnet tool install --global` = כלי טרמינל, לא קוד |
| מרימים Docker ל-DB | 20 דקות | `docker run` עם `-e`/`--name`/`-d` (חדשים מול היחידה הקודמת), `docker ps`/`docker logs` לאימות |
| Entities: Student/Grade | 15 דקות | הדגישו למה class ולא record כאן — EF Core צריך Properties ניתנים לשינוי |
| DbContext | 15 דקות | קונסטרוקטור עם `DbContextOptions` — קשרו ל-Constructor Injection מ-DI |
| Program.cs + AddDbContext | 20 דקות | מחרוזת חיבור מקטע-מקטע (Server, Database, User Id/Password, TrustServerCertificate) |
| הדגמה חיה: Migrations | 25 דקות | `migrations add` (מתכנן) מול `database update` (מבצע בפועל) — הראו את שני השלבים בנפרד |
| Controller + 2 endpoints | 25 דקות | GET/POST ישירות מול DbContext; `SaveChanges()` |
| מריצים ובודקים | 20 דקות | curl על שני ה-endpoints; הוכיחו persistence — restart ל-`dotnet run`, הנתונים עדיין שם |
| Navigation Properties | 10 דקות | תקציר בלבד — `List<Grade>` בתוך Student; העומק בשיעור העתידי על Queries |
| תרגול מודרך | 15 דקות | תרגיל 1+2 |

---

## דגשים להעברת השיעור

- זה שיעור שדורש סביבת עבודה תקינה לכולם **לפני** שמתחילים — ודאו ש-Docker Desktop רץ אצל כל סטודנט לפני חלק ה-DB, אחרת מבזבזים זמן שיעור על פתרון תקלות התקנה במקום על התוכן.
- ההדגמה החיה של `migrations add`+`database update` היא הליבה של השיעור — סטודנטים צריכים לראות בעיניים את קובץ ה-Migration שנוצר ואת הטבלה שמופיעה ב-DB בפועל, לא רק להאמין שזה קורה.
- הדגישו בתקיפות ש-`SaveChanges()` הוא לא "עוד קריאה" — זה **הרגע היחיד** שנתונים נכתבים בפועל. שכחת SaveChanges היא הבאג הכי נפוץ בשלב הזה.
- שלב ה"מריצים ובודקים" הוא לא קישוט — ההוכחה שדנה "שורדת" restart של `dotnet run` היא מה שממחיש בפועל את ההבדל בין DB אמיתי ל-`List<T>` בזיכרון מכל השיעורים הקודמים. אל תדלגו עליו.
- אם יש זמן, השוו קצרות ל-`InMemoryRepository` מיחידה קודמת — "`DbSet<T>.Add` נראה בדיוק כמו `List<T>.Add`, אבל התנהגות שונה לגמרי מתחת למכסה". הזכירו שה-Controller בשיעור הזה מדבר עם `DbContext` ישירות בכוונה (לצורך הוכחה מהירה), ושבשיעור הבא זה יתחבר כמו שצריך דרך ה-Repository.

---

## מושגים

**NuGet Package** — ספרייה חיצונית שמתווספת לפרויקט (`dotnet add package`), לא מובנית ב-.NET.
**ORM** — שכבת מיפוי בין אובייקטים לטבלאות SQL.
**`DbContext`** — חיבור לוגי למסד הנתונים, מקבל הגדרות חיבור דרך הקונסטרוקטור.
**`DbSet<T>`** — טבלה בודדת בתוך ה-DbContext.
**Connection String** — כתובת+פורט+שם DB+פרטי התחברות, כמחרוזת טקסט אחת.
**Code First** — מחלקות C# קודם, DB נבנה מהן.
**Migration** — קובץ שמתעד שינוי מבני ב-DB (`migrations add` מתכנן, `database update` מבצע).

---

## תרגיל חשיבה

**שאלת פתיחה:** "הוספתם שדה חדש למחלקת `Student` (למשל `PhoneNumber`), אבל לא הרצתם `migrations add`. מה קורה כשמנסים לשמור תלמיד חדש עם מספר טלפון?"

**מהלך:** תנו לסטודנטים לשער — התשובה: שגיאת ריצה, כי העמודה `PhoneNumber` פשוט לא קיימת בטבלה ב-DB בפועל. הובילו לתובנה: המחלקה ב-C# והטבלה ב-DB חייבות תמיד להישאר מסונכרנות — Migration היא **הגשר** שמבצע את הסנכרון הזה, לא פעולה אופציונלית.

**מה המרצה מראה בסוף:** הוסיפו שדה חדש למחלקה בשידור חי, נסו לשמור בלי Migration (הראו את השגיאה), ואז הריצו `migrations add`+`database update` ותנו לאותה שמירה להצליח — הדגמה ישירה של הצורך בסנכרון.
