דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. מבנה נתונים היררכי . EF CORE

מבנה נתונים היררכי . EF CORE

מתוזמן נעוץ נעול הועבר תכנות
11 פוסטים 3 כותבים 179 צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • מנצפךמ מנותק
    מנצפךמ מנותק
    מנצפך
    כתב ב נערך לאחרונה על ידי
    #1

    יש מוצר אב.
    למוצר אב יש קבוצת תוספים (מוצרים)
    שמכילה עוד מוצרים.

    דוגמה:
    אב: מחשב DELL

    קבוצת מוצרים מתאימים שמכילה: מסך, עכבר, מקלדת, מדפסת.

    הקבוצה הזאת יכולה להיות מקושרת לעוד מוצרי אב. כגון מחשב LENOVO

    גם למוצרים הבנים אפשר להוסיף עוד קבוצה שיש לה עוד מוצרים.

    כגון:
    למדפסת תהיה קבוצת תוספים שמכילה: דיו, דפים, טונר.
    והקבוצה הזאת יכולה להתאים לעוד מוצרים. כגון מדפסת HP, מדפסת CANON וכו'.

    לסיכום: יש כאן 2 אובייקטים בסה"כ
    מוצר. מכיל שם, מחיר ורשימת קבוצות מקושרת
    קבוצה: מכילה שם קבוצה ורשימת מוצרים בנים

     public class Item
     {
            public string Name { get; set; }
            public int Price{ get; set; }
    }
    
     public class Group
    {
            public string Name { get; set; }
    }
    

    אני רוצה לגשת למוצר ספציפי ולקבל את כל הקבוצות שלו ואת כל הבנים שלהם. ואם יש להם עוד קבוצות, לקבל את הקבוצות ואת הבנים שלהם.
    (לא צריך עד אין סוף. מספיק לי 3 דורות).

    כמו כן לגשת לרשימת כל המוצרים ולקבל את הנתונים כנ"ל.

    תגובה 1 תגובה אחרונה
    0
    • dovidD מחובר
      dovidD מחובר
      dovid ניהול
      כתב ב נערך לאחרונה על ידי dovid
      #2

      כדי שיהיה אפשר לענות, תערוך את הקוד ותוסיף את הקשרים בין שני הישויות.

      מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

      בכל נושא אפשר ליצור קשר dovid@tchumim.com

      תגובה 1 תגובה אחרונה
      3
      • מנצפךמ מנותק
        מנצפךמ מנותק
        מנצפך
        כתב ב נערך לאחרונה על ידי
        #3
        public class Item
            {
                public string Name { get; set; }
        
                public int? Id { get; set; }
                public int? Price { get; set; }
        
                public int? GroupId { get; set; }
                public Group Group { get; set; }
        
                public ICollection<Group> Groups { get; set; }
                public ICollection<Group2Item> Groups2Item { get; set; }
            }
        
         public class Group
            {
                [Key]
                public int? Id { get; set; }
        
                public string Name { get; set; }
        
                public List<Item> Items { get; set; }//parent
                public List<Group2Item> Group2Items{ get; set; }//parent
                
                public List<Item> ItemsChildren { get; set; }//children
        }
        
        
            public class Group2Item
            {   [Key]
                public int Id { get; set; }
        
                public int ItemId { get; set; }
                public Item Item { get; set; }
        
                public int GroupId { get; set; }
                public Group Group{ get; set; }
            }
        
        
          protected override void OnModelCreating(ModelBuilder modelBuilder)
                {
          modelBuilder.Entity<Item>()
                    .HasOne<Group>(i => i.Group)
                    .WithMany(o => o.ItemsChildren)
                    .HasForeignKey(i=> i.GroupId);
        
        
        
                    modelBuilder.Entity<Group>()
                .HasMany(g => g.Items)
                .WithMany(g=> g.Groups)
        
                .UsingEntity<Group2Item>(
                    j => j
                        .HasOne(pt => pt.Item)
                        .WithMany(t => t.Groups2Item)
                        .HasForeignKey(pt => pt.ItemId),
                    j => j
                        .HasOne(pt => pt.Group)
                        .WithMany(p => p.Group2Items)
                        .HasForeignKey(pt => pt.GroupId),
                    j =>
                    {  
                           j.HasKey(t => new { t.GroupId, t.ItemId });
                    });
        }
        
        תגובה 1 תגובה אחרונה
        0
        • מנצפךמ מנותק
          מנצפךמ מנותק
          מנצפך
          כתב ב נערך לאחרונה על ידי
          #4

          צריך לשים לב, במה שהראתי כאן, ITEM מחובר לקבוצה אחת בלבד כבן, אך יכול להיות מחובר למספר קבוצות בתור אב.

          אלו שני קשרים נפרדים.
          (לא עשיתי ש ITEM יוכל להתחבר לשני קבוצות, כי ITEM בעצמו הוא מימוש לאובייקט שלישי שלא הבאתי כאן, לדעתי אין בו עניין)

          תגובה 1 תגובה אחרונה
          0
          • dovidD מחובר
            dovidD מחובר
            dovid ניהול
            כתב ב נערך לאחרונה על ידי dovid
            #5

            מבחינתי הקוד הרלוונטי הוא כזה:

            public class Item
            {
            	public string Name { get; set; }
            
            	public int? Id { get; set; }
            	public int? Price { get; set; }
            
            	public int? GroupId { get; set; }
            	public Group Group { get; set; }
            }
            
            public class Group
            {
            	public int? Id { get; set; }
            	public string Name { get; set; }
            
            	public List<Item> ItemsChildren { get; set; }
            }
            
            

            אתה לא ציינת את העיקר, מה אתה הולך לעשות עם זה. זה לדעתי מאוד משנה. בכל אופן אם אקח את דבריך כפשוטם, ואניח שהמטרה היא שליפה של אובייקט יחיד עם כל צאצאיו רק בשלוש רמות, אפשר לכתוב את כל השלושה רמות מפורש בשאילתה, ככה:

            var item = db.Items.Where(i => i.Id == 12).Select(it =>
            	new
            	{
            		it.Name,
            		it.Price,
            		Group = new
            		{
            			it.Group.Name,
            			Items = it.Group.ItemsChildren.Select(it2 => new
            			{
            				it2.Name,
            				it2.Price,
            				Group = new
            				{
            					it2.Group.Name,
            					Items = it2.Group.ItemsChildren.Select(it3 => new
            					{
            						it3.Name,
            						it3.Price
            					})
            				}
            			})
            		}
            	});
            

            זה לא נראה אלגנטי אבל זה יעבוד טוב.
            אם רוצים שליטה על יותר רמות של היררכיה, אני חושב שאין מנוס מלעשות לולאה, שממלאת מחלקות מתאימות.
            אם רוצים מיטוב ולעשות הכל ברמת הSQL אפשר לעשות שאילתות מורכבות שמתעסקות ברקורסיה כזאת (אני רואה על זה הרבה בגוגל sql tree structure query), ולוותר בנקודה הספציפית הזאת על הEF.

            מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

            בכל נושא אפשר ליצור קשר dovid@tchumim.com

            תגובה 1 תגובה אחרונה
            3
            • מנצפךמ מנותק
              מנצפךמ מנותק
              מנצפך
              כתב ב נערך לאחרונה על ידי
              #6

              אוקי.
              בעצם זו עבודה ידנית לפלטר את מה שבדיוק רוצים.
              חשבתי ש EF יפתור לי את זה.

              אני שמח שלא טעיתי בזה ש EF לא אמור להתמודד עם סוג מבנה מידע כזה.

              בכל אופן, אני יכול לעשות שם אולי רקורסיה? בשביל להביא את כל המידע הרלוונטי.

              תגובה 1 תגובה אחרונה
              0
              • yossizY מנותק
                yossizY מנותק
                yossiz
                כתב ב נערך לאחרונה על ידי
                #7

                רקורסיה על מבנה היררכי ב-SQL נעשה בד"כ על ידי Recursive CTE. אבל מחיפושי גוגל נראה שזה לא נתמך ב-EF.
                אם תעשה את זה ברמת SQL תקבל רשימה שטוחה, אין עצים ב-SQL (כאשר עושים JOIN, אז EF יודע לפרסר את התשובה ולבנות ממנה עץ).
                הרקורסיה שאתה יכול לעשות ב-EF זה מה ש@dovid כתב:

                אני חושב שאין מנוס מלעשות לולאה, שממלאת מחלקות מתאימות

                📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

                תגובה 1 תגובה אחרונה
                2
                • מנצפךמ מנותק
                  מנצפךמ מנותק
                  מנצפך
                  כתב ב נערך לאחרונה על ידי
                  #8

                  התכוונתי רקורסיה על המידע שEF הביא.
                  במקום לעשות כל דור בנפרד.
                  אביא דוגמה בל"נ בהמשך

                  yossizY תגובה 1 תגובה אחרונה
                  0
                  • yossizY מנותק
                    yossizY מנותק
                    yossiz
                    השיב למנצפך ב נערך לאחרונה על ידי
                    #9

                    @מנצפך אם זה מספיק לך, אז למה לא (אבל זה יצא הרבה שאילתות). הבנתי שאתה רוצה את הכל בשאילתה אחת.

                    📧 יוסי@מייל.קום | 🌎 בלוג | ☕ קפה

                    תגובה 1 תגובה אחרונה
                    2
                    • מנצפךמ מנותק
                      מנצפךמ מנותק
                      מנצפך
                      כתב ב נערך לאחרונה על ידי
                      #10

                      מבחינת SQL זה שאילתה אחת. (כי עשיתי include ו - thenInclude)
                      אחרת, ה SELECT לא יביא כלום

                      תגובה 1 תגובה אחרונה
                      1
                      • מנצפךמ מנותק
                        מנצפךמ מנותק
                        מנצפך
                        כתב ב נערך לאחרונה על ידי
                        #11

                        בסוף, הפתרון כנראה הוא ברמת הקליינט (ווב).
                        לקחתי מהשרת רשימה של items ושל group בנפרד. (כולל הקשרים הקרובים אליהם)
                        ואת הקשרים עשיתי עם לולאה פשוטה בצד לקוח.
                        זה פשוט משחזר את המבנה כמו שהתקבל בשרת.

                        וכנראה זה פתרון אמיתי ונכון.

                        תגובה 1 תגובה אחרונה
                        0

                        בא תתחבר לדף היומי!
                        • התחברות

                        • אין לך חשבון עדיין? הרשמה

                        • התחברו או הירשמו כדי לחפש.
                        • פוסט ראשון
                          פוסט אחרון
                        0
                        • דף הבית
                        • קטגוריות
                        • פוסטים אחרונים
                        • משתמשים
                        • חיפוש
                        • חוקי הפורום