On this page
מערך שיעור: Queries מתקדמות — Include, N+1
משך: 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 שמודפס אוטומטית |
| הרעיון: Include | 15 דקות | JOIN מפורש, עדיין שאילתה אחת בקונסולה |
| הבעיה: N+1 בפעולה | 25 דקות | לולאה בלי Include — ספרו יחד עם הסטודנטים כמה שאילתות מופיעות בקונסולה |
| הפתרון: Include לפני הלולאה | 15 דקות | אותה לולאה בדיוק, תיקון אחד — שאילתה אחת בקונסולה |
| endpoint + curl | 13 דקות | GET .../with-grades, אימות סופי שגם ה-API וגם הקונסולה תקינים |
| Deferred Execution | 10 דקות | מתי שאילתה באמת רצה |
| תרגול מודרך | 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, ומדדו שוב. ההבדל המספרי בפועל (לא רק “יותר שאילתות”) הוא מה שהופך את הנושא למוחשי וזכיר.