משיב מוביל
שמירת דטה סט למסד הנתונים, עם קשרי גומלין.

שאלה
-
זה נראית לי שאלה בסיסית מאוד,
כאשר אני מנסה לעדכן את מסד הנתונים ע"י דטה אדפטר מטבלאות דטה סט (שנוצר אוטומטית ע"י הכלים של VS), לא נשמר קשר הגומלין (1:רבים) שקיים בין השורות שנוספו.
הבעיה כמובן משום שאת הערך של השדה הראשי המשמש כמפתח לקשר מוגדר AutoIncerment (הן במסד הן בדטה סט).
מה הדרך שאמורים לעשות?
תודה רבה מראש!
תשובות
-
עליך לשנות את הגדרות ברירת המחדל של ה-Relation בתוך ה-DataSet
פתח את ה-Designer של ה-DataSet
במידה ולא עשית שינויים אזיי אמור להיות קו שמחבר בין שתי הטבלאות
קו זה מייצג את ה-Relation מנקודת המבט של ה-DataSet
תעשה Double Click על הקו
יש לשנות את "Choose what to create" ל-"Both relation and constraint"
יש לשנות את "Update Rule" ל-"Cascade"
זה אמור לעשות את העבודה
אורי
- סומן כתשובה על-ידי Eran Sharvit יום שני 16 יולי 2012 08:21
כל התגובות
-
לא הבנתי למה הבעיה שהוא מוגדר AI, שיהיה גם מפתח PRIMARY
מה שכן אם אני זוכר אז כשקוראים לטבלה בדוט נט צריך ידנית להגדיר שם מה המפתחות
-
אולי אין בעיה, רק שברגע הUpdate של טבלת הבנים, ישנה שגיאה של הפרת מפתח.
למעשה, השדה המוגד כמפתח זר בשורת הבן נשאר -1 במקום לקבל את הערך שקיבלה שורת האב, ע"י הAI.
בכל מקרה אני לא נגעתי בהגדרת הדטה סט, כי אני יוצר אותה ע"י האשף. המפתח מוגדר אוטומטית בדיוק כפי שצריך, שלא כדבריך.
-
-
הענין הוא שהדטה סט לא יכול לדעת מהו המספר שצריך לתת עד ביצוע הupdate כי יתכן ועודכנו עוד רשומות ממקור אחר..
לכן הפיתרון הוא שאילתה מיוחדת אחרי ביצוע העדכון הראשון כמו זה למשל
אני לא מצפה שיידע קודם העדכון.
רק שאחרי שהוא מעדכן את טבלת האב, ומאכלס בשדה האוטומטי את הערך הנכון (זה באמת קורה), וממילא יידע מה לקבוע בעדכון טבלת הבנים (וזה כבר לא קורה..).
-
היה עוזר אם היית מצרפת לנו קוד של מה שאת עושה לפחות (או אפ אפשר את הפקויירט עם הבעיה).
בעקרון אם את עובדת בצורה נקייה ישירה עם שאילתות ואת רוצה למצוא את המספר האחרון בטור מסוג identity שנוצר לך כשהכנסת נתון חדש את יכולה להעזר בפונקציה המובנית ב SQL בשם SCOPE_IDENTITY. פונקציה זו מחזירה לך את הערך האחרון בסקופ הנוכחי
למשל (זה קוד של SQL שאת יכולה להריץ ממשק הניהול של מסד הנתונים SSMS):
declare @T as table( id int identity, txt nvarchar(10) ) insert @T select 'asfsd' union select 'fdg' union select 'fdgh' union select 'vcxb' union select 'cvb sd' select * from @T GO select SCOPE_IDENTITY() GO
הערה: לא כתבת לנו אפילו באיזה טכנולוגיה את עובדת.
בעקרון ניתן להריץ את 2 הפעולות שאת רוצה ביחד בשאילתה אחת או תחת טרנזקציה אחת ואז את בטוחה שהן מבוצעות ביחד או נכשלות ביחד והמספר שאת מקבלת הוא אכן המיספור האחרון שהוכנס על ידך
תוכלי לראות בקישור הבא כיצד עובדים עם טרנזקציות ב asp.net
http://www.c-sharpcorner.com/uploadfile/dchoksi/transaction02132007020042am/transaction.aspx
- נערך על-ידי pituachMVP, Moderator שבת 07 יולי 2012 08:46
-
-
א. תודה על רצונך לעזור.
ב. אני לא מבין איזה קוד אתה רוצה לראות, אחרי ההסבר המפורט, אבל אשלח בע"ה תיכף בסוף ההודעה.
ג. אני מכיר היטב את הSCOPE_IDENTITY, ולא רק אני, אלא גם הדטה סט שנוצר אוטומטית ע"י הVS מכיר את זה ומשתמש בזה גם.
ד. הטכנלוגייה היא דטה סט של דוט נט, "strongly typed", שנוצר אוטומטית ע"י הכלי Add Data Sourcen שזמין בטכנלוגיות דסטקופ (Winforms, WPF).
הנה הקוד, שלא אמור לדעתי לשפוך הרבה אור על השאלה. החלק הארי של הקוד בעצם זה קוד שנוצר אוטומטי ע"י הVS על פי קובץ הXSD של הדטה סט.
Dim ds As New TestsDataSet Dim DataAdapterPerson = New TestsDataSetTableAdapters.personsTableAdapter Dim DataAdapterContacts = New TestsDataSetTableAdapters.ContactsTableAdapter 'new row in parent table "Person" Dim dr = ds.persons.NewpersonsRow dr.Name = "AA" dr.Status = False dr.CancelEdit() ds.persons.AddpersonsRow(dr) 'new row in parent table "Contacts" Dim subDr = ds.Contacts.NewContactsRow subDr.Value = "B" subDr.personsRow = dr 'כאן נוצר הקשר בין שורת הבן לשורת האב. ds.Contacts.AddContactsRow(subDr) 'save data to database DataAdapterPerson.Update(ds.persons) DataAdapterContacts.Update(ds.Contacts)
לדעתי הקוד מאוד לא מובן כי השדות של הטבלאות שנוצרו בעצם על פי מסד הנתונים הפכו למאפיינים, כך שאין שום אבחנה איפה אני מייחס את שורת הבן לשורת האב, והאם זה תקני.
אשמח עדיין לעזרה.
- נערך על-ידי לומדים יום ראשון 08 יולי 2012 09:06
-
היי
קודם כל לא הבנתי למה התכוונת בסעיף ב במילים "אחרי ההסבר המפורט" מכיוון אני לא רואה שום הסבר מסודר ועד עתה (עד לתגובה האחרונה שלך) אפילו לא ידעתי באיזה טכנולוגיה אתה עובד :-)
עתה יש לנו הרבה יותר מידע כדי לעזור
באופן מעשי כל מה שכתבתי נכון לגבי כל טכנולוגיה וזה הפתרון והשאלה שנשארה כרגע היא רק כיצד ליישם את הפתרון בהתאם לוכנולוגיה איתה אתה עובד.
בטכנולוגיות WIN (השם שלי לטכנולוגיות שאתה קורא להם טכנולוגיות דסטקופ) כמו WPF או winform וכו' יש הבדל מהותי מאוד גדול לעומת עבודה בטכנולוגיות WEB בהקשר לבעיה הספציפית כאן וזה שטכנולוגיות WIN יכולות לשמור על קשר פתוח רציף למסד הנתונים בעוד בטכנולוגיות WEB כל "עמוד" הוא כאילו הרצה נפרדת (זו ברירת המחדל מסיבה ברורה שהלקוח מרוחק וכל העבודה היא בסגנון לקוח-שרת)
מה שזה אומר שלגבי יישום העניין הוא שאני לא יכול בדיוק לעזור כרגע מפני שבטח יש אפשרויות מובנות שאני לא מכיר בטכנולוגיה WPF למשל. ולכן אני מציע לחפש חומר על נושא טרנזקציה בטכנולוגיה בה אתה עובד (הדוגמה שהבאתי מעל היא בטכנולויית asp.net שהיא כמובן טכנולוגיית WEB)
-
pituach, תודה על האכפתיות והיחס.
אבל אינני מצפה ממך לתשובה בנידון. למה? אם היית לפעמים משתמש בכלי עליו דיברתי - יוצר הדטה סט האוטומטי של הVS, היית מבין אותי היטב כבר מפתיחת האשכול.
ואם אינך משתמש בכלי, אין סיבה שתצליח לעזור לי - השאלה היא יותר פרקטית (איך משתמשים בכלי זה למטרה זו) ולא תיאורתית מה אומורים לעשות.
ובחזרה לשאלה, מקוה שמישהו מכיר:
אין קשר בין טרנזקציה לעניין - חד משמעי. לא אכפת לי אם בין עדכון לעדכון נמחקו/התווספו/עודכנו 1000 שורות.. בפועל יש לי בהצלחה מרובה טבלה מעודכנת עם זיהוי אוטומטי מעודכן, כל מה שאני רוצה שהדטה סט יעשה פעולה מתבקשת - שיוך נכון של שורות הבנים.
הנ"ל נכון בכל פלפורמה וטכנלוגיה דוטנטית, כאשר משתמשים בכלי הנ"ל, שבפועל זמין רק בפלפורמות דסטקופ.
תודה מראש,
עדיין לא נושעתי..
-
גם אני לא משתמש בכלים האוטומטים אבל מצורף לינק למצב דומה
-
- נערך על-ידי pituachMVP, Moderator יום רביעי 11 יולי 2012 00:25
-
גם אני לא משתמש בכלים האוטומטים אבל מצורף לינק למצב דומה
-
מכיון שלא נראה שאנחנו מצליחים לתת לך פתרון :(
אני ממליץ לך לעבור לפורומים באנגלית ששם יש יותר אנשים ויכול להיות שלהם יהיה פתרון.
בכל מקרה נשמח לשמוע על התובנות ודך הפתרון שמצאת לנכון לפתור את הבעיה שלך.
לפי מיטב הבנתי הקינפוג שלך נכון ולא בטוח שיש פתרון אוטומטי.
אני יכול לספר לך על מקרה שהיה לי על אותו עקרון בסיס נתונים מרכזי ולפטופים עם בסיס נתונים אישי שהיו אמורים לעדכן את המרכזי.
עלו כל מני אפשרויות פיתוח כגון:
בזמן סינכרון מול בסיס הנתונים הראשי לבצע את ההכנסה מחדש ואז מחיקה של בסיס הנתונים בלפטופ וסינכרון מחדש עם המספור החדש.
שימוש ב identity עם קפיצות לפי מספר הלפטופים ככה לפטופ 1 יהיה בקפיצות של 11,21,31,41
אבל הפתרון הנכון היה מהפכני ובדיוק נכנס לבסיסי הנתונים (בשנת 2000) שימוש ב GUID וככה לבטל את השימוש ב IDENTITY וזה גם ההמלצה שלי במקרה הזה.
אומנם זה לא פותר את הבעיה אלה עוקף אותה אבל גם זה פתרון.
-
שימוש ב identity עם קפיצות לפי מספר הלפטופים ככה לפטופ 1 יהיה בקפיצות של 11,21,31,41
תוספת קטנה: בשרתי SQL 2012 נוסף משהו שקיים כבר הרבה שנים בשרתים אחרים כמו אורקל וזה Sequence. אם תבצע מה שאתה אומר כאן (אני לא אומר שזה רע ואני מבצע את הרבה במערכות חיות.... אני רק מצביע על החסרון) ומחר תרצה להוסיף עוד מחשב יש לך בעיה.
כאמור Sequence פותר את הבעיות האלו מפני שהוא אלמנט חיצוני בניגוד ל IDENTITY שהוא אלמנט בטבלה. Sequence מאפשר פשוט להריץ מיספור רציף משותף לכל הטבלאות למשל.
הערה: עם כל הייתרונות של שימוש ב GUID אסור לשכוח את החסרונות. למשל מדובר בטור הרבה הרבה יותר גדול. האינדקסים יהיו גדולים יותר (יתפסו יותר PAGE-ים וזה אומר יותר פעולות), המקום בדיסק גדול יותר והזכרון שידרש גדול יותר.
-
ל GUID כמובן שיש חסרונות ואישית אני לא אוהב להשתמש בו. אבל המציאו אותו וזה נותן אחלה פתרון (אפילו הפורומים כאן משתמשים בזה תראה את ה URL)
כמובן שהפתרון של הקפיצות לא נכון וזו הייתה רק אחת מהאפשרויות ובשנת 2000 לא יכולתי להגיד להם תלכו עם מודם סלולרי.
אך גם הפתרון של SEQUENCE לא פותר את הבעיה.
לצורך העניין וההבנה (אני יודע שיש CACHING מספר מינמלי מקסימלי קפיצות וכו) מדובר בטבלה שמחזיקה מספור וכל פעם שרוצים להזין מספר רץ חדש שולפים מספר משם.
זה לא היה פותר את הבעיה של הלפטופים. וגם לא של "לומדים".
ובמילת תודה.
תודה שגרמת לי לחקור קצת על עוד פונקציה של ה SQL.
כיף קצת לצאת מהשיגרה :)
- נערך על-ידי tetitu יום חמישי 12 יולי 2012 08:25
-
עליך לשנות את הגדרות ברירת המחדל של ה-Relation בתוך ה-DataSet
פתח את ה-Designer של ה-DataSet
במידה ולא עשית שינויים אזיי אמור להיות קו שמחבר בין שתי הטבלאות
קו זה מייצג את ה-Relation מנקודת המבט של ה-DataSet
תעשה Double Click על הקו
יש לשנות את "Choose what to create" ל-"Both relation and constraint"
יש לשנות את "Update Rule" ל-"Cascade"
זה אמור לעשות את העבודה
אורי
- סומן כתשובה על-ידי Eran Sharvit יום שני 16 יולי 2012 08:21
-