האם יש דרך לקרוא לאובייקט ללא סוג?
-
בחלון החיפוש אני נותן למשתמש לסנן ע"פ כל מיני פרמטרים, ולבסוף אני עושה שאילתת איחוד בין הליסט של התרומות לליסט של התורמים ומציג לו את כל הנתונים בדטהגריד.
אני רוצה להוסיף לו אופציה של ייצוא הנתונים לקובץ CSV (אבל לא זה הקטע העקרוני.. מצידי שיהיה גם לPDF..) או להדפסה.
הבעיה שלי היא שאני לא יכול לשלוח אובייקט כזה להמרה או להדפסה, כיון שלאובייקט שנוצר אין סוג שהרי הוא מאוחד מאובייקט של Donor ושל Donation (סוגים של מחלקות שלי :lol: ).
השאלה האם יש דרך להתגבר על זה, כגון להשתמש בדינאמיק או משהו כזה? ואם כן, כיצד?
תודה רבה!
אברהםהקוד של האיחוד הוא:
var newlistDonors = from o in donatFilter join d in AddTorem.donors on o.IdDonor equals d.Id select new { d.Id, o.IdDonation,o.IsActive, d.FirstName, d.LastName,d.Gender, d.Adress, d.Tel, d.Email, o.SumDonation, o.SumAllDonat, o.StartDonation, o.SumMonthDonat, o.ActualMonthlyDonation};
פורסם במקור בפורום CODE613 ב03/09/2015 00:14 (+03:00)
-
תודה רבה על העזרה!
כתבתי כך:public static ObservableCollection<object> listResult; var newlistDonors = from o in donatFilter join d in AddTorem.donors on o.IdDonor equals d.Id select new { d.Id, o.IdDonation,o.IsActive, d.FirstName, d.LastName,d.Gender, d.Adress, d.Tel, d.Email, o.SumDonation, o.SumAllDonat, o.StartDonation, o.SumMonthDonat, o.ActualMonthlyDonation}; //אחסון של המשתנה האנונימי במשתנה מוכר כדי שנוכל לייצא אותו listResult = (ObservableCollection<object>)newlistDonors;
ואני מקבל בזמן ריצה את השגיאה הנ"ל:
"אין אפשרות לבצע המרה של אובייקט מסוג '<JoinIterator>d__14[Person.Donation,Person.Donor,System.Int32,<>f__AnonymousType0
14[System.Int32,System.Int32,System.Boolean,System.String,System.String,Person.Gender,System.String,System.String,System.String,System.Double,System.Double,System.DateTime,System.Int32,System.Int32]]' לסוג 'System.Collections.ObjectModel.ObservableCollection`1[System.Object]'." stringבאותה מידה כשניסיתי להגדיר מראש שהLINQ ישמור במשתנה מסוג אובייקט ולהגדיר select new Object אז הוא נתן לי שגיאה דומה בזמן קומפילציה.
ולא כ"כ הבנתי למה אמרת שהוא ללא שם, הרי נתתי לו שם: var newlistDonors??
תודה רבה!פורסם במקור בפורום CODE613 ב04/09/2015 00:32 (+03:00)
-
מצאתי כאן קישור איך להמיר טיפוס אנונימי לאובייקט קיים.
אולם, הבעיה שלי היא שהטיפוס האנונימי שלי לא מתאים לאובייקטים שלי, כיון שהוא מאוחד משני אובייקטים.
האם אין דרך אחרת אלא לכתוב מחלקה שכוללת בתוכה את כל המאפיינים של 2 האובייקטים, ואז להשתמש בקוד הנ"ל??
ממש מוזר שאין דרך פשוטה לעשות זאת, הרי בטח זה מאד שימושי כשמריצים חיפוש בדטהבייס ורוצים לשלוף מידע מכמה טבלאות, ולהציג אותו ללקוח ולאפשר לו לייצא אותו, לא?
תודה רבה ושבת שלום!פורסם במקור בפורום CODE613 ב04/09/2015 16:33 (+03:00)
-
למה בכלל צריך את LINQ ?
פשוט תעבור בלולאה על שני הרשימות ותשמור ברשימה שלישית את אלא שעומדים בתנאיםאיך אני אשמור ברשימה שלישית? ליסט של איזה אובייקט זה יהיה??
או שאתה מתכוון שאני אצור אובייקט שלישי שמאוחד (חלקית) משני הראשונים, ואליו אשמור אותם, זה נראה לי סתם מיותר לכתוב עוד מחלקה כבר עדיף להשתמש באובייקט אנונימי, לא???פורסם במקור בפורום CODE613 ב05/09/2015 23:35 (+03:00)
-
דבר ראשון אובייקט אנונימי זה לצרכים של תת שאילתה ודברים כאלה ש"לא שווים" תחזוקה של עיצוב מחלקה. זה עולה ביצועים טיפונת יותר ממלקה של ממש ותמיד יש לשקול אם לעשות צ'יק צ'ק מחלקונת שמכילה את המאפיינים הנדרשים.
במידה וצריך לשלוח את התוצאות לפונקציה אחרת, לאחסן במשתנה וכדומה, אני בטוח שכדאי ליצור מחלקה בשביל זה.דבר שני מאוד קל לעשות קאסט בLINQ, או בסלקלט עצמו:
select (object) new { d.Id, o.IdDonation,o.IsActive, d.FirstName, d.LastName,d.Gender, d.Adress, d.Tel, d.Email, o.SumDonation, o.SumAllDonat, o.StartDonation, o.SumMonthDonat, o.ActualMonthlyDonation};
או עם הפונקציה Cast אחרי הסלקט:
listResult = ObservableCollection<object>(newlistDonors.Cast<Object>);
אבל זה ממש לספורט כי זה ממש א הגיוני להמיר אובייקט אנונימי לסוג אובייקט, כי זה בלתי הפיך: לא תוכל לגשת לשום מאפיין אם לא דרך שיקוף שהוא יקר הן בביצועים הן בתחזוקה.
פורסם במקור בפורום CODE613 ב05/09/2015 23:48 (+03:00)
-
למה בכלל צריך את LINQ ?
פשוט תעבור בלולאה על שני הרשימות ותשמור ברשימה שלישית את אלא שעומדים בתנאים
מן הסתם זה יהיה פי מאה יותר מהר מאשר ש- LINQ עושה את זה.במקרים כאלה דוקא LINQ ינצח בקלות לולאה פרימיטבית. JOIN של LINQ משתמש במילון פנימי, ואילו בלולאה פרימטיבית אתה חייב לולאה פנימית שמחפשת כל פעם את האיבר, וזה פי שלוש לרעת הלולאה לפחות. אם תתחכם ותעשה מיון וחיפוש בינארי אזי תנצח, אבל רחוק מאוד מפי מאה (משהו כמו פי 10 וזה דוקא בהתפלגות טובה ובהרבה מאוד איברים).
LINQ בד"כ מועדף בגלל קריאות וקלות תחזוקה. אבל גם בביצועים הוא בסדר ועלותו אם בכלל זניחה.פורסם במקור בפורום CODE613 ב06/09/2015 00:17 (+03:00)
-
דוד תודה רבה על ההרחבה בהסברים!!!
קיבלתי, והוספתי מחלקה שלישית (עשיתי שהיא תירש מאחת מהמחלקות הראשונות, וככה נשאר לי רק להוסיף את המשתנים של המחלקה השניה :lol:
זה בסדר? או שאסור לעשות ככה ?!?!ומה הכוונה שהjoin משתמש במילון פנימי?
פורסם במקור בפורום CODE613 ב06/09/2015 00:30 (+03:00)
-
אם אתה יורש רק כדי לחסוך הקלדה, אז לא עושים כך, אבל אם יש בזה צורך אז תירש למה לא.
@דוד ל.ט.
במקרים כאלה דוקא LINQ ינצח בקלות לולאה פרימיטבית. JOIN של LINQ משתמש במילון פנימי, ואילו בלולאה פרימטיבית אתה חייב לולאה פנימית שמחפשת כל פעם את האיבר, וזה פי שלוש לרעת הלולאה לפחות. אם תתחכם ותעשה מיון וחיפוש בינארי אזי תנצח, אבל רחוק מאוד מפי מאה (משהו כמו פי 10 וזה דוקא בהתפלגות טובה ובהרבה מאוד איברים).
ההגיון אומר שכל דבר שהוא גנארי חייב לבדוק המון בדיקות תקינות, וחייב להיות גמיש וממילא הוא בוודאי הרבה איטי מאשר משהו שנבנה באופן יעודי.
באיזה מילון הוא משתמש? גם אתה יכול להשתמש במילון?פורסם במקור בפורום CODE613 ב06/09/2015 00:57 (+03:00)
-
קיבלתי, והוספתי מחלקה שלישית (עשיתי שהיא תירש מאחת מהמחלקות הראשונות, וככה נשאר לי רק להוסיף את המשתנים של המחלקה השניה :lol:
זה בסדר? או שאסור לעשות ככה ?!?!לא. ירושה זה יותר להרחבה של צורך קיים. פה אתה סתם צריך "מחסן".
אני הייתי יוצר מחלקה שיש לה שתי מאפיינים: תורם ותרומה.
וכעת אני חושב שהכי פשוט זה להשתמש עם מחלקה קיימת, שמה Tuple. שימושה היא ליצור סט של מאפיינים ללא יצירת מחלקה מתאימה. אז ככה:public static ObservableCollection<Tuple<Donor, Donation>> listResult; var newlistDonors = from o in donatFilter join d in AddTorem.donors on o.IdDonor equals d.Id select Tuple.Create(o, d); listResult = new ObservableCollection<Tuple<Donor, Donation>>(newlistDonors);
פורסם במקור בפורום CODE613 ב06/09/2015 10:59 (+03:00)
-
ההגיון אומר שכל דבר שהוא גנארי חייב לבדוק המון בדיקות תקינות, וחייב להיות גמיש וממילא הוא בוודאי הרבה איטי מאשר משהו שנבנה באופן יעודי.
באיזה מילון הוא משתמש? גם אתה יכול להשתמש במילון?אתה צודק בהכל חוץ מהמילה "הרבה". יש ליופי של LINQ תקורה, אבל שולית.
סוג המילון הוא Lookup (ממש דומה לDictionary). אתה יכול כמובן לראות: http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,581.
לא הבנתי מה הכוונה האם גם אני יכול. אגב אם כבר ממשים לבד יש ודאי שיפורים לעשות אבל מבזבזים את הכח והזמן לבנות ייעודית במקומות זניחים לגמרי.פורסם במקור בפורום CODE613 ב06/09/2015 11:09 (+03:00)
-
@דוד ל.ט.
אני הייתי יוצר מחלקה שיש לה שתי מאפיינים: תורם ותרומה.
וכעת אני חושב שהכי פשוט זה להשתמש עם מחלקה קיימת, שמה Tuple. שימושה היא ליצור סט של מאפיינים ללא יצירת מחלקה מתאימה. אז ככה:public static ObservableCollection<Tuple<Donor, Donation>> listResult; var newlistDonors = from o in donatFilter join d in AddTorem.donors on o.IdDonor equals d.Id select Tuple.Create(o, d); listResult = new ObservableCollection<Tuple<Donor, Donation>>(newlistDonors);
טוב, התגברתי על העצלות :lol: וכתבתי מחלקה חדשה לגמרי, ואז ראיתי את ההודעה שלך :lol: :lol:
בכל אופן גם אם אני משתמש במחלקה שלי וגם אם אני משתמש בtuple אני מקבל בשורה האחרונה את הודעת השגיאה הבאה:
אין אפשרות לבצע המרה של אובייקט מסוג '<JoinIterator>d__14[Person.Donation,Person.Donor,System.Int32,System.Tuple
2[Person.Donation,Person.Donor]]' לסוג 'System.Collections.ObjectModel.ObservableCollection1[System.Tuple
2[Person.Donor,Person.Donation]]'.
כשהשתמשתי במחלקה שלי כתבתי select new ואת שם המחלקה, וכבר שם קיבלתי את השגיאה הנ"ל...
מה עושים????? :shock: :shock:
ותודה רבה רבה על כל העזרה!!!!פורסם במקור בפורום CODE613 ב06/09/2015 11:16 (+03:00)
-
טוב, התגברתי על העצלות :lol: וכתבתי מחלקה חדשה לגמרי, ואז ראיתי את ההודעה שלך :lol: :lol:
זה היומיום של מתכנת טוב...
אני מכיר כאלה שלא כותבים שום דבר לחינם, ובגלל זה גם לא יוצא להם שוב דבר טוב.פורסם במקור בפורום CODE613 ב06/09/2015 11:24 (+03:00)
-
@דוד ל.ט.
אתה טועה בבניית הObservableCollection.
תראה איך כתבתי בשורה 6. ותראה איך אתה עשית.כבר שם הוא זרק לי את השגיאה בזמן הכתיבה ולכן ביצעתי המרה מפורשת...
אבל זה לא עזר לי והוא זורק לי את החריג בזמן ריצהפורסם במקור בפורום CODE613 ב06/09/2015 11:26 (+03:00)
-
כתבתי כך:
var newlistDonors = from o in donatFilter join d in AddTorem.donors on o.IdDonor equals d.Id select Tuple.Create(o, d); listResult = new ObservableCollection<Tuple<Donor, Donation>>((ObservableCollection<Tuple<Donor, Donation>>)newlistDonors);
פורסם במקור בפורום CODE613 ב06/09/2015 11:28 (+03:00)
-
טוב, התגברתי על העצלות :lol: וכתבתי מחלקה חדשה לגמרי, ואז ראיתי את ההודעה שלך :lol: :lol:
אני מתנצל שלא שיתפתי אותך בטיפ נוסף פשוט מאוד (אני למדתי להשתמש בו לא מזמן):
אתה משנה את הnew לnew XXX כשהXXX זה שם מחלקה שאתה בוחר שעדיין לא קיימת. כמובן שהשם נצבע באדום. אתה מקיש Ctrl+. בעוד הסמן על המילה. מופיע לך תפריט ואז לחץ אנטר. נוצרת מחלקה חדשה עם כל המאפיינים.. סילחה שהחמצתי מלומר לך זאת בהתחלה.פורסם במקור בפורום CODE613 ב06/09/2015 11:33 (+03:00)
-
@דוד ל.ט.
אתה טועה בבניית הObservableCollection.תראה איך כתבתי בשורה 6. ותראה איך אתה עשית.
כבר שם הוא זרק לי את השגיאה בזמן הכתיבה ולכן ביצעתי המרה מפורשת...
אבל זה לא עזר לי והוא זורק לי את החריג בזמן ריצההObservableCollection מקבל בבנאי אוסף מהסוג הגנרי שלו.
לא צריך לעשות המרה, וגם אי אפשר! ממתי אוסף הוא צאצא של ObservableCollection?! - קאסטינג זה להפוך מחלקה יורשת למחלקה מורישה. כמו לשנות Button של WPF לControl שזה מאבות אבותיו...פורסם במקור בפורום CODE613 ב06/09/2015 11:36 (+03:00)
-
@דוד ל.ט.
אני מתנצל שלא שיתפתי אותך בטיפ נוסף פשוט מאוד (אני למדתי להשתמש בו לא מזמן):
אתה משנה את הnew לnew XXX כשהXXX זה שם מחלקה שאתה בוחר שעדיין לא קיימת. כמובן שהשם נצבע באדום. אתה מקיש Ctrl+. בעוד הסמן על המילה. מופיע לך תפריט ואז לחץ אנטר. נוצרת מחלקה חדשה עם כל המאפיינים.. סילחה שהחמצתי מלומר לך זאת בהתחלה.אין לך מה להתנצל זה ממש ממש חזק!!!
@דוד ל.ט.
הObservableCollection מקבל בבנאי אוסף מהסוג הגנרי שלו.
לא צריך לעשות המרה, וגם אי אפשר! ממתי אוסף הוא צאצא של ObservableCollection?! - קאסטינג זה להפוך מחלקה יורשת למחלקה מורישה. כמו לשנות Button של WPF לControl שזה מאבות אבותיו...החכמתי!! לא חשבתי שהמרה זה דווקא ממוריש ליורש...
בכל אופן בלא המרה הוא זורק לי את אותה השגיאה:
Argument 1: cannot convert from 'System.Collections.Generic.IEnumerable<System.Tuple<Person.Donation, Person.Donor>>' to 'System.Collections.Generic.List<System.Tuple<Person.Donor, Person.Donation>>'
כיצד אפשר להתגבר על כך?
ותודה רבה רבה על כל ההשקעה בעניית התשובות וההסברה!!פורסם במקור בפורום CODE613 ב06/09/2015 15:45 (+03:00)