On this page
מערך שיעור: 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 ותנו לאותה שמירה להצליח — הדגמה ישירה של הצורך בסנכרון.