משך: 2.5 שעות אקדמיות (113 דקות).

מטרת השיעור: הסטודנטים יבינו למה Navigation Properties לא נטענות אוטומטית, ויזהו וימנעו בעיית N+1 — ויראו את זה בעיניים בקונסולה שלהם, לא רק כתיאוריה.

בסוף השיעור הסטודנטים צריכים: להשתמש ב-Include לטעינת קשרים, לזהות קוד שגורם ל-N+1 (ולספור את השאילתות בקונסולה), ולהסביר Deferred Execution.

דגש קריטי: N+1 היא שאלת-ראיון-עבודה קלאסית לתפקידי Backend — ודאו שסטודנטים יכולים להסביר אותה בביטחון עם דוגמה, לא רק הגדרה. חדש השיעור הזה: EF Core כבר מדפיס כל שאילתה לקונסולה בסביבת פיתוח, בלי שום הגדרה נוספת — זה הכלי המרכזי של כל השיעור, לא תוספת אופציונלית.


מהלך השיעור

חלק בשיעורמשךהערות ודגשים
פתיחה וחיבור5 דקותהראו student.Grades ריק בלי Include — “למה?”
LINQ על DbSet + רואים SQL בקונסולה15 דקותהריצו שאילתה פשוטה, הראו את ה-SQL שמודפס אוטומטית
הרעיון: Include15 דקותJOIN מפורש, עדיין שאילתה אחת בקונסולה
הבעיה: N+1 בפעולה25 דקותלולאה בלי Include — ספרו יחד עם הסטודנטים כמה שאילתות מופיעות בקונסולה
הפתרון: Include לפני הלולאה15 דקותאותה לולאה בדיוק, תיקון אחד — שאילתה אחת בקונסולה
endpoint + curl13 דקותGET .../with-grades, אימות סופי שגם ה-API וגם הקונסולה תקינים
Deferred Execution10 דקותמתי שאילתה באמת רצה
תרגול מודרך15 דקותתרגיל 1+2

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

  • אל תדלגו על שלב “רואים SQL בקונסולה” כ"עוד הדגמה" — זה הכלי שדרכו הסטודנטים יוכיחו לעצמם כל שלב אחר כך, כולל ה-N+1. ודאו שכולם רואים את ההדפסה אצלם לפני שממשיכים.
  • הדגישו ש-N+1 היא לא “באג נדיר” — היא נופלת בקלות רבה כשמישהו לא-מודע לנושא ניגש ל-Navigation Property בלולאה, קוד שנראה תמים לגמרי.
  • Deferred Execution שווה הדגמה קצרה משלו — כתבו שאילתת LINQ, הראו שכלום “לא קרה” עד .ToList() (אפשר לראות את זה גם בקונסולה — שום הדפסה עד לשם).

מושגים

Include — טעינת Navigation Property במפורש, בשאילתה אחת. N+1 Problem — שאילתה נפרדת לכל איבר בלולאה, במקום JOIN יחיד. Deferred Execution — שאילתת LINQ רצה רק ב-.ToList()/foreach.


תרגיל חשיבה

שאלת פתיחה: “יש לכם דף שמציג 1000 תלמידים עם הציונים שלהם. בלי Include, כמה שאילתות SQL בערך יישלחו ל-DB? מה זה עושה לזמן הטעינה של הדף?”

מהלך: תנו לסטודנטים לחשב — 1001 שאילתות (1 + 1000). הובילו לתובנה שזה לא “קצת יותר איטי” — זה פער ביצועים דרמטי, שיכול להפוך דף שאמור להיטען תוך שברירי שנייה לדף שנטען שניות ארוכות, במיוחד עם latency רשת אמיתי בין השרת ל-DB.

מה המרצה מראה בסוף: אם אפשר, הריצו קוד עם N+1 אמיתי מול 100+ רשומות, ומדדו זמן ריצה (Stopwatch) — ואז אותו קוד בדיוק עם Include, ומדדו שוב. ההבדל המספרי בפועל (לא רק “יותר שאילתות”) הוא מה שהופך את הנושא למוחשי וזכיר.