דמיינו לכם מצב תיאורטי. יש לכם מתודה, שהתפקיד שלה הוא לעדכן מסד נתונים שעובד עם LINQ to SQL. אתם רוצים לקבל איזשהו אובייקט שאמור להחליף ישות קיימת ב DB. למשל, יש לנו את האובייקט User שמציין ישות מהDB, ואנחנו רוצים מתודה שתקבל אובייקט User שהוא זה שקיים עכשיו ואובייקט User שהוא החדש, שאמור להחליף אותו, ואנחנו רוצים לעדכן באמצעות LINQ to SQL.
בכל הדוגמאות, רואים שאתה משנה את ה properties של האובייקט בתוך ה context של ה DataContext, וכאשר אתה עושה SubmitChanges מזוהים השינויים והעדכון מתבצע. הדבר הזה מתבצע למעשה באמצעות כך, שכל פרופרטי שנמצא כחלק מישות שמופתה ממסד הנתונים, מבצע בתהליך ה set שלו כמה פקודות, שלמעשה, מיידעות את ה data context שהיה שינוי, וכך כשנעשה SubmitChanges הוא יידע מה לעדכן.
עד כאן הכל טוב ויפה. אבל עדיין, בגלל זה, אנחנו לא יכולים להגיד משהו כמו CurrentUser=NewUser ולצפות שיתבצע שינוי וכל הנתונים שב NewUser יועתקו ל CurrentUser וה Data Context באמת יידע לעדכן את הDB ולהריץ את משפט ה update המתאים.
ניסיון לעשות Attach במקרה הזה לא יעבוד וייזרק exception, בגלל שהאובייקט שמועבר לא משוייך למעשה ל DataContext הנוכחי ונושא state ממקודם, ואי אפשר לעשות Attach לאובייקט שאינו חדש (כלומר, נצטרך בתיאוריה לעשות Clone מלא לאובייקט). כלומר, הקוד הבא פשוט לא יעבוד. השורה הראשונה תהיה חסרת משמעות, כי לא יובחן שהיה שינוי, והשורה השנייה בכלל תזרוק Exception (כל אחד מהם זה פיתרון אפשרי שונה):
לכן, כדי בכל זאת לקחת את כל הנתונים מהאובייקט החדש ולהעביר אותם לאובייקט הישן ולוודא שעדיין המידע יתעדכן בDB - צריך לעשות משהו קצת פחות יפה - Reflection. מה שנעשה, זה למעשה לעבור על כל ה properties של האובייקט הנוכחי שנלקח מהDB (שה DataContext עוקב אחרי השינויים שלו) ונשנה עבור כל property ל property המקביל באובייקט שמייצג את הישות המחליפה, החדשה (יש כל מיני דרכים לבצע את זה, חיפוש בגוגל יביא לכם כל מיני גישות שונות לנושא - זאת אחת מהם):
(לחץ על התמונה להגדלה)
למעשה, באמצעות החילוף ערכים הזה, והעתקת כל הערכים מהאובייקט עם הנתונים החדשים ל properties התואמים באובייקט המקור, אנחנו מבטיחים שה data context יידע שהיו שינויים ויריץ את משפט ה UPDATE המתאים כשנעשה SubmitChange, וכך נוכל למעשה להחליף ערכים של אובייקט אחד, שמייצג את הערכים העדכניים, בערכים של אובייקט אחר.
שימו לב, שחשוב מאד לבדוק מה ה Type של ה properties שאנחנו נוגעים בהם. אנחנו לא רוצים לגעת ב properties של EntitySet שמייצגים את ה realationships שבין הטבלאות. זה עלול ליצור בעיות.
בהצלחה.