
הטקסט המלא של הדקות הראשונות בהרצאה «Dataset - מפתח ראשי - Primary Key» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
אוקיי, אז בשיעור הקודם מה שראינו זה עבודה בקישור סגור, כאשר מה שאנחנו עשינו זה לקחנו טבלה אחת שהייתה במסד הנתונים, העתקנו אותה לעותק נפרד, הבאנו אותו לצד של אתר האינטרנט, עבדנו מקומית עליו באתר האינטרנט, וכאשר רצינו לבצע שמירה במסד הנתונים, פשוט שמרנו את כל השינויים בחזרה למסד.
כאשר עשינו את זה, אז כשהבאנו את העותק, פתחנו קישור, הבאנו עותק, כשרצינו להחזיר, שוב פתחנו קישור והחזרנו.
במהלך העבודה הקישור היה סגור. כעת אנחנו הולכים להרחיב את התוכנית הזאת, כך שאנחנו נעבוד עם כמה טבלאות. מה זה אומר? במסד הנתונים הרי יכולים להיות לנו מספר טבלאות, ויכול להיות קישור ביניהם.
הקישור שקיים במסד הנתונים שומר על תקינות המידע. לדוגמה, אם אנחנו נמצאים במסד נתונים Northwind ואנחנו עובדים איתו, יש לנו את הטבלה Products.
בטבלה Products אנחנו בעצם רואים שיש לנו Category ID, כלומר ה-ID של הקטגוריה של המוצרים. מה זאת אומרת קטגוריה ID?
יש לנו את טבלת קטגוריז ובטבלת קטגוריז יש לנו קוד קטגוריה שמתאר כל קטגוריה בנפרד מהי. קטגוריה ID בטבלת קטגוריז זה המפתח הראשי של טבלת קטגוריז, כלומר הקטגוריות השונות שקיימות למוצרים.
אז אנחנו רואים ש-Beverages שזה משקאות יש לה קטגוריה אחת, Condiments שזה תבלינים יש לה קטגוריה מספר 2, ואז אם אנחנו רוצים בטבלת המוצרים לומר לאיזו קטגוריה שייך המוצר, אז אנחנו יכולים לדוגמה לומר שצ'אי בעצם זה קטגוריה מספר אחת, כלומר משקאות.
וכך אנחנו יכולים להגדיר שצ'אי שייך לקטגוריה מספר אחת, בלי לשכפל יותר מדי מידע, אלא רק המפתח הראשי שהיה בטבלת categories הופך להיות מפתח זר בטבלת products בעמודת category ID. אם אני כרגע אנסה להכניס קטגוריה שלא קיימת, בואו נסתכל איזה קטגוריה לא קיימת.
טבלת קטגוריז, אני רואה שיש לי קטגוריות 1 עד 8. טבלת פרודקטס, אני בא ואני אומר אוקיי, קטגוריה ID של צ'אי הולך להיות קטגוריה 9, אין לי קטגוריה כזאת.
ברגע שאני אלחץ על Enter, אני רואה שמסד הנתונים מייצר לי שגיאה ואומר לי תקשיב, אין קטגוריה כזאת, יש קשר בין טבלת פרודקטס לבין טבלת קטגוריז ולכן אתה לא יכול להכניס מידע בקטגורי ID עבור פרודקטס, כאשר המידע הזה לא היה קיים לפני זה בטבלת קטגוריז ואין בעצם קטגורי ID כזאת.
זאת אומרת שמסד הנתונים מכיל קשר כזה ושומר על תקינות המידע עקב הקשר הזה. בואו נחזיר את זה לאחד. אנחנו עכשיו רוצים לשמור על תקינות המידע גם כאשר אנחנו מביאים אותו לצד האפליקציה.
מה זה אומר? בדאטאבייס יש לנו שתי טבלאות, אנחנו הולכים לעבוד בקישור סגור, ואנחנו עכשיו הולכים להביא את שתי הטבלאות האלה, עותק שלהם, בואו נשכפל אותו, עותק שלהם לצד אתר האינטרנט ולעבוד מקומית עם שתי הטבלאות.
מה זה אומר? זה אומר שאנחנו הולכים להכניס מידע לטבלת products שנמצאת עותק מקומי בצד של אתר האינטרנט אבל אנחנו רוצים שהמידע הזה יהיה תקין ולכן אנחנו מביאים גם את טבלת categories.
הבעיה היא שב-idio.net כאשר אנחנו מביאים שתי טבלאות אנחנו מסוגלים לשמוע אותם באובייקט מיוחד שנקרא data set בניגוד לאובייקט הקודם שעבדנו איתו שנקרא data table.
הבעיה היא שהקשר לא מגיע אוטומטית ולכן אנחנו נצטרך לאחר שהבאנו את שתי הטבלאות האלה ליצור בעצמנו את אותו קשר בין שתי הטבלאות בצד של האפליקציה.
וכך אנחנו יכולים לשמור שהמידע שאנחנו מכניסים מקומית לאחת הטבלאות באמת זה מידע חוקי שנשמר בהתאם לטבלה השנייה.
אחרי שסיימנו את כל זה, אנחנו פשוט יכולים לבצע שמירה של המידע שוב במסד הנתונים ולהחזיר את כל המידע ששונה בחזרה למסד הנתונים. אוקיי, אז בואו נסתכל איך בעצם זה מתבצע.
אנחנו נחזור לאפליקציה, יש לנו את האתר הזה שראינו אותו שיעור שעבר ובעצם בנינו אותו בשיעור שעבר ואנחנו הולכים להרחיב אותו. אז דבר ראשון אנחנו לא הולכים להביא רק את פרודקטס, אנחנו הולכים להביא גם את פרודקטס וגם את טבלת קטגוריז.
אז בואו נשנה ראשית את הפונקציה getProducts כך שהיא תיקרא getProducts and categories. יש לנו כאן כמובן את הסמארט טאג האדום הזה שבעזרתו אנחנו יכולים לומר לכל הדף הנוכחי תשנה את השם getProducts ל-getProducts and categories.
בואו נלחץ וכל השמות שונו. הדבר הבא שאנחנו רוצים לעשות אנחנו לא רוצים להעביר רק דאטה טייבל. דאטה טייבל מסוגלת לשמור טבלה אחת בלבד אנחנו רוצים שתי טבלאות או יותר במקרים אחרים, ולכן אנחנו נשנה את זה לדאטה סט.
אנחנו צריכים אבל לשנות את זה בכל מקום, לכן בואו נחזיר ונגדיר את פונקציית ה-replace. Find and Replace בכל מקום שכתוב Data Table תשנה לי ל-Data Set.
אז בואו נחליף את זה, Replace ראשון, שני, שלישי, המערכת מאתרת לי בכל מקום ומחליפה לי ל-Data Set.
אחרי שהחלפנו ל-Data Set בואו נבצע עוד כמה שינויים. כעת אנחנו רואים שיש לנו פה שם שנקרא Products Table. בואו נאתר את השם הזה ושוב נשנה אותו בכל האפליקציה ל-Products and Categories.
שוב, קונטרול H יביא לנו את חלון ה-Find and Replace ונשנה את זה ל-Products and Categories. Replace גם כאן, גם כאן, Replace, כל מקום שהוא מוצא נשנה כי אנחנו רוצים דאטה סט שמכיל לנו את שתי הטבלאות.
אוקיי, עוד מעט אנחנו נשנה את השגיאות האלה ותכף נראה ממה הן נובעות. אז מה בעצם אנחנו מביאים?
יש לנו פה Object Data Set. Object Data Set זה אובייקט שמסוגל לשמור בתוכו מספר טבלאות. אנחנו ראינו שטבלה נשמרת על ידי Object Data Table.
Data Set בעצם זה מעין אוסף, אובייקט שמכיל אוסף של טבלאות. אם אני ניגש כרגע לאובייקט עצמו אני רואה שיש לי אוסף שנקרא טייבלס, ואני יכול לגשת לטבלה על ידי המיקום שלה, אינדקס, או שאני יכול לגשת לטבלה על ידי השם שלה ואז יהיה סטרינג.
בעצם כל טבלה שנשמרת כאן, הטיפוס שלה, אם אנחנו נסתכל על האינטליסנס זה data table. בואו נסתכל על זה.
אנחנו רואים כאן שברגע שאני פונה לטבלה מסוימת, אז חוזר לי אובייקט data table רגיל שכבר עבדנו איתו.
זאת אומרת שאובייקט data set מחזיק אוסף שנקרא tables, שכל פריט בו זה data table רגיל שעבדנו איתו.
בנוסף, אובייקט הדאטה סט מחזיק בתוכו עוד אוסף שנקרא ריליישנס וזה הכישורים בין הטבלאות שהוא מחזיק בכדי לשמור על תקינות המידע.
כל אובייקט מטיפוס ריליישן באוסף הזה הוא מטיפוס דאטה ריליישן שמתאר לי קשר אחד בין שתי טבלאות. ואנחנו צריכים קודם כל להביא שתי טבלאות ולא טבלה אחת.
באדפטר בשיעור הקודם אנחנו אמרנו Select Product ID Product Name Uniprice From Products זאת אומרת שהבאתי שלוש עמודות מטבלה אחת ויחידה שהיא product.
בואו נחזיר בנוסף לשלושת העמודות האלה גם את עמודת category ID בכדי שנוכל לבצע שם שינויים. דבר נוסף שאני רוצה לעשות, כשאני מביא את הטבלה על ידי פונקציית fill, האדפטר כמובן ניגש למסד הנתונים ומבצע עותק של הטבלה.
אני נתתי לו כאן עכשיו אובייקט מטיפוס data set. מה שהאדפטר עושה הוא פשוט יוצר אובייקט חדש מטיפוס data table ומוסיף אותו לאוסף הטבלאות שראינו בתוך אובייקט ה-data set.
מה שאנחנו צריכים לעשות רק זה להגדיר שם עבור הטבלה שלנו בפונקציית פיל. נהוג שהשם הזה יהיה אותו השם של הטבלה במסד הנתונים, זאת אומרת כשאנחנו מביאים כרגע את טבלת פרודקטס אז ניתן את השם פרודקטס אבל זה יכול להיות כל שם אחר.
זה סתם שם מקומי שאנחנו נותנים מעין כינוי עבור הטבלה. אז כעת הבאנו רק את טבלת פרודקטס. עכשיו אני רוצה לומר לאדפטר תוסיף לי עוד טבלה שזאתי טבלת קטגוריז לכן אני צריך ללכת לאדפטר ולאתר שם את Select Command שזה אובייקט SQL Command שכבר עבדנו איתו, ולומר לו Command Text נוסף שאומר תביא לי
את כל העמודות From Categories. אחרי שעשינו את זה שוב פעם אנחנו צריכים ללכת ולהביא פיזית את המידע, ושוב מתבצע על ידי Adapter.Fill.
אני שולח ל-Fill שוב פעם את הדאטה סט שיש לי, אבל הפעם אני נותן שם אחר לטבלה שהיא Categories. מה שאנחנו עשינו כרגע והבאנו לאותה דאטה סט גם את טבלת פרודקטס שתוארה כאן וגם את טבלת קטגוריז שתוארה כאן ועכשיו הדאטה סט הזה מחזיק לי שתי טבלאות אבל כמו
שראינו מקודם הוא לא מחזיק לי את הקישור ביניהם ADO.NET לא מביאה אוטומטית את הקישורים שנמצאים במסד הנתונים שזה איזשהו חיסרון שקיים ב-ADO.NET ואנחנו צריכים עכשיו להוסיף קישור כזה.
איך אנחנו עושים את זה? אנחנו ניגשים לדאטה סט שלנו לאוסף ה-relation שמקודם ראינו ומוסיפים relation חדש. ראשית אנחנו נותנים ל-relation שם, ניתן לו categories-products כל שם יכול להיות חוקי.
הדבר הבא שאנחנו מוסיפים זה איזו עמודה הקשר מתבצע כאשר העמודה הראשונה שאנחנו מוסיפים זאת העמודה שקיימת בטבלת ה-parent. מה זה אומר טבלת ה-parent?
במסד הנתונים ראינו שיש לנו שתי טבלאות, קרודקטס וקטגוריז ביניהן קיים קשר עבור העמודה קטגורי ID. בשתי הטבלאות קיימת עמודה קטגורי ID שהיא מקושרת אחת עם השנייה.
בעמודה אחת בטבלה אחת יותר נכון העמודה היא המפתח הראשי שבה הערך לא יכול לחזור פעמיים. בטבלה השנייה העמודה נקראת מפתח זר שבה כמובן הערך יכול לחזור פעמיים.
בקטגוריז זאת העמודה עם המפתח הראשי כי אנחנו לא יכולים להגדיר שתי קטגוריות עם אותו ID ולכן העמודה הזאתי בטבלת קטגוריז זאת העמודה עם המפתח הראשי.
בטבלת פרודקס כמובן שיכולים להיות לי מספר מוצרים עם אותה קטגוריה ולכן זאת העמודה עם המפתח הזר. אז הטבלה קטגוריז נקראת טבלת פרנט והטבלה פרודקס נקראת טבלת צ'יילד.
טבלת הפרנט סך הכל זאת הטבלה עם העמודה עם המפתח הראשי. אז בואו נחזור לקוד שלנו ואנחנו רואים שאנחנו אנחנו צריכים לתת קודם כל את העמודה שנחשבת פרנט.
איך אנחנו מבצעים את זה? אתם יכולים לראות את זה כאן, פרנט. אז אנחנו צריכים לגשת ראשית לדאטה סט שלנו, לאתר את הטבלה שבה יש את העמודה עם המפתח הראשי וזאת כמובן הטבלת קטגוריז.
השם שתיארתי כאן צריך להיות בדיוק אותו השם שנתתי מקומית עבור טבלת הקטגוריז. לאחר שאיתרתי את הטבלה עצמה אני פונה לאוסף ה-columns שלה ופונה לעמודה שהיא המפתח הראשי.
העמודה הזאת כמובן נקראת category ID. ויש לי כרגע אובייקט מטיפוס column, או יותר נכון data column ששלחתי לקישור שלנו. בואו נראה כאן שורה שנראה את הכל בקוד, ונוסיף כרגע את העמודה הבאה.
העמודה הבאה שלנו זאת עמודת ה-child. עמודת ה-child גם נמצאת בדאטה סט שלנו. פעם הטבלה היא טבלת product, ניגש לאוסף העמודות ושוב נאתר עמודה שנקראת CategoryID וכעת יצרנו אובייקט ריליישנשיפ שקיים בתוך הדאטה סט שלנו הוא נקרא CategoriesProducts שם שרירותי אבל משמעותי שנתתי והקשר מתבצע בין עמודת
CategoryID שנמצאת בטבלת Categories לבין עמודת CategoryID שנמצאת בטבלת Products. עכשיו אם אנחנו ננסה להכניס מידע שגוי עבור טבלת פרודקטס שלא נמצא בטבלת קטגוריז, הקשר הזה שהוספנו עכשיו ישמור שאנחנו לא נוכל לבצע את זה, והוא כמובן יעלה חריגה
או אקספצ'ן שאנחנו נצטרך לטפל בה. הדבר הבא שאנחנו נשנה כרגע בשביל שיהיה יותר מתאים לתרגיל זה את המפתח שהכנסנו בתוך הקאש.
במקום שנקרא למפתח הזה פרודקטס, בואו נקרא לו פרודקטס אנד קטגוריז.