Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Many to many relationship

Îåêßíçóå áðü ôï ìÝëïò pitaridis. Τελευταία δημοσίευση από το μέλος KelMan στις 18-05-2013, 01:43. Υπάρχουν 10 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  09-05-2013, 15:38 72571

    Many to many relationship

    Μέχρι τώρα όλα τα Project που έχω κάνει είναι σε ASP.NET αλλά εδώ και μερικές μέρες με έχει βάλει το αφεντικό μου στο τρυπάκι να μπούμε στον κόσμο του ASP.NET MVC. Έχω προχωρήσει αρκετά αλλά έχω κολλήσει σε μία many to many relationship. Για βρω λύση δημιούργησα ένα απλό project με Authors και Books. Το model μου έχει την ακόλουθη δομή:

     

    namespace AuthorsAndBooks.Models
    {
        public class Author
        {
            public Author()
            {
                this.AuthorsToBooks = new HashSet<AuthorToBook>();
            }

            public int AuthorID { get; set; }
            public string Name { get; set; }
            public string Surname { get; set; }

            public virtual ICollection<AuthorToBook> AuthorsToBooks { get; set; }
        }
    }

    namespace AuthorsAndBooks.Models
    {
        public class Book
        {
            public Book()
            {
                this.AuthorsToBooks = new HashSet<AuthorToBook>();
            }

            public int BookID { get; set; }
            public string Title { get; set; }

            public virtual ICollection<AuthorToBook> AuthorsToBooks { get; set; }
        }
    }

     

    namespace AuthorsAndBooks.Models
    {
        public class AuthorToBook
        {
            public int AuthorToBookID { get; set; }
            public int AuthorID { get; set; }
            public int BookID { get; set; }

            public virtual Author Author { get; set; }
            public virtual Book Book { get; set; }
        }
    }

    namespace AuthorsAndBooks.Models
    {
        public class MyDbContext : DbContext
        {
            public DbSet<Author> Authors { get; set; }
            public DbSet<AuthorToBook> AuthorsToBooks { get; set; }
            public DbSet<Book> Books { get; set; }
        }
    } 

     

    Στο view edit έχω τις ακόλουθες εντολές:

     

    @{
        ViewBag.Title = "Edit";
        AuthorsAndBooks.Models.MyDbContext db = new AuthorsAndBooks.Models.MyDbContext();
        var Results = from b in db.Books
                      join ab in db.AuthorsToBooks on b.BookID equals ab.BookID
                      where ab.AuthorID.Equals(Model.AuthorID)
                      select b;
    }

     

    Και στο HTML για να εμφανίσω τα checkboxes έχω τις ακόλουθες γραμμές:

     

    <br /><b>Books</b><br />
    @foreach (var item in Results)
    {
        <input name="CategoryIDs" id="[email protected]" type="checkbox" value="@item.BookID" checked="checked" />@item.Title<br />
    }

     

    Τα checkbox εμφανίζονται στην οθόνη μου κανονικά το θέμα είναι μετά τις αλλαγές πώς μπορώ στον Controller μου να βρω τις αλλαγές που έχουν γίνει στα checkbox ώστε να ενημερώσω τη βάση δεδομένων μου;

  •  09-05-2013, 22:02 72572 σε απάντηση της 72571

    Απ: Many to many relationship

    Πολύ καλή επιλογή το MVC αν τα Project σας είναι μεγάλα και πολύπλοκα αλλά ακόμα και για μικρότερα δεν θα έλεγα όχι.

    Τώρα για αυτό που ρώτησες, μπορεί να γίνει με διάφορους τρόπους και όπως πάντα ο κάθε ένας έχει τα συν και τα πλην.

    Ο πρώτος είναι να περάσεις σαν hidden html tags τις αρχικές τιμές των Check Boxes έτσι ώστε στο Post method του controller να μπορείς να δεις την αρχική με την νέα τιμή αν έχει αλλαχθεί. Δεν τον προτείνω, απλά τον αναφέρω σαν μία επιλογή. Το γιατί είναι μία άλλη συζήτηση.

    Ο δεύτερος είναι να χρησιμοποιήσεις το Session και να βάλεις εκεί τις αρχικές τιμές. Οπότε μετά κάνεις μία σύγκριση. Φαντάζομαι αρκετούς να μην συμφωνούν με αυτή την λύση, αλλά θα πρέπει να παραδεχθούμε ότι είναι δυνατόν να γίνει. Το αν πρέπει είναι και αυτό μία άλλη συζήτηση.

    Και ο τρίτος είναι να φέρεις τις εγγραφές από την βάση να συγκρίνεις και να αποθηκεύσεις.

    Μπορεί να υπάρχουν και άλλοι τρόποι, αλλά αυτούς έχω τώρα στο μυαλό μου.

    Μία παρατήρηση στον κώδικα που είδα και που θα σε βοηθήσει στην συνέχεια. Μην γράφεις κώδικα που έχει να κάνει με ανάκτηση εγγραφών μέσα στο View. Αυτό θα πρέπει να γίνεται στον Controller ο οποίος είτε θα αναφέρεται σε κάποιο Repository ή ο πιο dirty τρόπος να αναφέρεται στο Entity Framework. Δεν γράφουμε όμως κώδικα μέσα στο View.

    Αυτό που θα πρέπει να κάνεις είναι να φτιάχνεις ένα ViewModel το οποίο θα γεμίζει ο controller με δεδομένα και θα περνάς αυτό το ViewModel στο View. Οπότε ότι Linq γράψεις στο View να έχει να κάνει με τα Objects τους ViewModel και όχι με τα Application Domain Objects. Το MVC είναι πάρα πολύ καλό να δίνει την δυνατότητα στον προγραμματιστή να μπορεί να τηρεί το Separation of Concerns και με το να γράφεις κώδικα ανάκτησεις μέσα στο View είναι λάθος τακτική.

    Ένα πάρα πολύ καλό site είναι το www.asp.net στο section MVC για να σε βοηθήσει να ξεκινήσεις. Είναι must για αυτόν που ξεκινάει με το MVC με παραδείγματα για το κάθε τι.

  •  10-05-2013, 00:09 72573 σε απάντηση της 72572

    Απ: Many to many relationship

    Ευχαριστώ για την απάντηση αλλά μάλλον δεν κατάλαβες ποιο είναι το πρόβλημα μου. Δεν μπορώ από τον Controller να δώ ποια checkbox έχουν ενεργοποιηθεί από το χρήστη μετά το πάτημα του submit. Πώς μπορώ με λίγα λόγια να έχω πρόσβαση στην τιμή των input που βρίσκονται στην σελίδα.

     

    Όσο για το σωστό τρόπο του MVC, έχω κατανοήσει αρκετά καλά (έτσι νομίζω τουλάχιστον) το που πρέπει να τοποθετήσω το τον κώδικα και το γεγονός ότι το view δεν είναι το κατάλληλο σημείο απλά προς το παρών προσπαθώ να λύσω το πρόβλημα που έχω με την υλοποίηση της διαχείρισης των δεδομένων για το many to many relationship.

     

    Αν μπορείτε λοιπών να μου πείτε πώς θα έχω πρόσβαση στις τιμές των Checkbox που έχω τοποθετήσει στην σελίδα θα ήμουν πολύ ευτυχισμένος. Έχω ψάξει αρκετά στο google αλλά έχω βρει μόνο πώς μπορείς να πάρεις τιμές που έχουν συνδεθεί με κάποια πεδία του model.

  •  10-05-2013, 05:23 72574 σε απάντηση της 72573

    Απ: Many to many relationship

    Αν κατάλαβα καλά έχεις μία λίστα από βιβλία στα οποία δίπλα θέλεις να εμφανίσεις ένα checkbox. Ο χρήστης με την σειρά του επιλέγει κάποια checkbox τα οποία εσύ θέλεις να δεις ποια είναι. Αυτό κατάλαβα. Αν κάνω λάθος το δέχομαι αλλά από αυτά που γράφεις αυτό βγαίνει. Και ο πιο σωστός τρόπος για να το κάνεις αυτό στο mvc είναι ο παρακάτω.

    Δημιουργείς ένα ξεχωριστό model το οποίο θα φτιάξεις για τις ανάγκες του συγκεκριμένου view και για αυτό το λέμε view model. Δεν έχει καμία σχέση αυτό το model με τα domain models αλλά απλά το δημιουργούμαι για να μπορέσουμε να δουλέψουμε με το view, τα html tags να δημιουργηθούν και το binding στο post να δουλέψει σωστά με τον λιγότερο κόπο από εμάς.

    Αυτό το view model θα το ονόμαζα CheckedBookViewModel το οποίο θα είχε τρία properties. Checked: Boolean, BookTitle: String, BookId: integer.

    Στον controller θα έκανα το select από την βάση θα δημιουργούσα μία λίστα από CheckedBookViewModel και για κάθε βιβλίο θα έκανα instantiate ένα νέο instance CheckedBookViewModel.

    Την λίστα στο τέλος θα την περνούσα στο view. Οπότε το view θα ήταν ένα typed view τύπου IEnumerable(Of CheckedBookViewModel) και αν χρησιμοποιήσεις το code scaffolding θα σου έφτιαχνε και αυτόματα τον κώδικα δημιουργίας της λίστας με τα βιβλία και το Checkbox.

    Στο Post τώρα θα έβαζα σαν παράμετρο της μεθόδου μία λίστα από CheckedBookViewModel έτσι ώστε όταν όταν ο χρήστης πατήσει submit να δουλέψει το binding και να ενημερωθεί η λίστα με τα CheckedBookViewModel. Οπότε μέ ένα iteration βλέπεις πια έχει τσεκάρει ο χρήστης.

    Αν μέχρι εδώ πάμε καλά, και όντως έχω καταλάβει αυτό που ζητάς να συνεχίσω και με το υπόλοιπο που συνδέει το αρχικό post με αυτό τώρα, δηλαδή το πως θα ξέρω αν ένα βιβλίο πριν το post ήταν check και έγινε uncheck ή και το αντίστροφο. Αν πάλι έχω καταλάβει λάθος συγνώμη.

  •  10-05-2013, 08:23 72576 σε απάντηση της 72574

    Απ: Many to many relationship

    Βασικά δεν μιλάμε για μία απλή λίστα βιβλίων. Στην πραγματικότητα δεν υπάρχουν 2 πίνακες αλλά 3. Ο ένας έχει τους Authors, ο άλλος τα βιβλία και ο τρίτος είναι ο ενδιάμεσος πίνακας όπου για παράδειγμα βάζουμε συνδέσεις ανάμεσα στους authors και στα βιβλία.

     

    Από τη στιγμή που ξέρουμε ποιον author επεξεργαζόμαστε, απλά χρειάζεται να βρούμε πια βιβλία έχουν τσεκαριστεί και αφού διαγράψουμε όλες τις εγγραφές του ενδιάμεσου πίνακα να τις ξαναδημιουργήσουμε μόνο για τα βιβλία που έχει τσεκάρει ο χρήστης. Αυτό σημαίνει ότι δεν χρειάζεται κάποιου είδους έλεγχο, απλά θέλει μια διαγραφή και μία εισαγωγή για κάθε τσεκάρισμα.

     

    Τη διαχείριση των δεδομένων μπορώ να την κάνω μέσω του DbContext. Το πρόβλημα μου είναι πώς θα πάρω τα βιβλία που έχουν τσεκαριστεί. Απλά χρειάζομαι μία λίστα με BookIDs. Αυτό που μου λες ότι πρέπει να κάνω είναι να φτιάξω ένα νέο model ώστε να μεταφέρω τις πληροφορίες από το view στον controller. Γενικότερα αυτό δεν μου ακούγεται και πολύ καλό γιατί με την ίδια λογική θα πρέπει να ξαναφτιάξω ένα νέο model για την επεξεργασία των βιβλίων που θα μπορώ να επιλέξω από μία λίστα με checkbox ποιοι είναι οι Authors του βιβλίου.

     

    Σε ASP.NET τέτοιου είδους διαχείριση είναι πανεύκολη και δεν μπορώ να καταλάβω γιατί όλοι πάνε στο ASP.NET MVC αν κάνει τη ζωή του προγραμματιστή πιο δύσκολη. Εκτός από το να φτιάξω καινούριο model δεν μπορώ με κάποιο τρόπο να πάρω από το request τις τιμές που δεν είναι στο model;

  •  10-05-2013, 14:33 72580 σε απάντηση της 72576

    Απ: Many to many relationship

    Δεν γνωρίζω πως τέτοιου είδους διαχείριση είναι εύκολη στα WebForms. Ίσως να οφείλεται στο View State που υπάρχει εκεί και δεν υπάρχει στο MVC.

    Αυτό που δεν ακούγεται καλό με τα View Models είναι και ο πιο σωστός τρόπος που ταιριάζει και με την φιλοσοφία του MVC. Για αυτό και τα παραδείγματα που βλέπεις στο Google τα περισσότερα είναι με κάποιο model.

    Ναι ένας προγραμματιστής γράφει περισσότερο στο MVC αλλά το κέρδος είναι αργότερα όταν το project μεγαλώσει, γίνει πιο πολύπλοκο και τηρηθεί σωστά το Separation Of Concerns. Δεν θα έχεις δει καλύτερο οργανωμένο κώδικα. Άλλωστε δεν είναι τυχαίο που μεγάλα και πολύπλοκα site στρέφονται στο mvc. Συν το γεγονός ότι είναι και πιο γρήγορο από τα WebForms.

    Ο ModelBinder όταν ένα request έρχεται από έναν browser έχει σε τέσσερα σημεία να κοιτάξει για να βρει τα property values. Στο Request.Form, RouteData.Values, Request.QueryString & στο Request.Files. Θα μπορούσες δηλαδή να είχες ένα checkbox το οποίο δεν είναι bind επάνω σε κάποιο model να του έδινες name="checkbox" και μετά μέσα στον controller να έγραφες Request.Form("checkbox") οπότε έτσι θα έπερνες το value του checkbox χωρίς να είναι bind κάπου. Αυτό νομίζω είναι που ζητάς, αλλά να γνωρίζεις πως δεν τείνουν να γίνονται έτσι τα πράγματα στο mvc.

  •  10-05-2013, 21:54 72581 σε απάντηση της 72571

    Απ: Many to many relationship

    Θα συμφωνήσω απόλυτα με την λύση που προτείνει ο George σχετικά με την δημιουργία ενός viewmodel για τις ανάγκες της συγκεκριμένης οθόνης. Προσωπικά πιστεύω πως είναι η βέλτιστη προσέγγιση μιας και το viewmodel μπορεί να περιέχει μόνο τα απαραίτητα δεδομένα για την οθόνη ή πολλές φορές σε μια οθόνη θέλουμε περισσότερα του ενός, ας πούμε domain models. Γενικά δεν μ αρέσει η χρήση αντικειμένων που έχουν business value να χρησιμοποιούνται ως μοντέλα στο view για πολλούς λόγους.

    Και κάτι ακόμη, αυτό που μπορώ να υποθέσω είναι ότι η σχέση είναι πολλά προς πολλά γιατί ένα βιβλίο μπορεί να έχει γραφτεί από έναν ή και περισσότερους συγγραφείς. Σε τι όμως χρησιμεύει να έχει η κλάση αυτή δικό της id και να είναι ξεχωριστή οντότητα. Το entity framework μπορεί εύκολα να χειριστεί many to many relationships χωρίς ενδιάμεση κλάση κάτι που θα έκανε το μοντέλο σου πιο απλό. Βέβαια μπορεί να μου διαφεύγει κάποια λεπτομέρεια.


    My dream is to fly over the rainbow so high!!!!
  •  13-05-2013, 07:50 72588 σε απάντηση της 72581

    Απ: Many to many relationship

    Ο ενδιάμεσος πίνακας είναι η τεχνική που χρησιμοποιώ στο ASP.NET και πάντα έδινα ένα μοναδικό ID σε κάθε εγγραφή.

     

    Θα μπορούσατε να μου δώσετε ένα μικρό παράδειγμα για το πώς θα το υλοποιήσω το σενάριο που μου προτείνετε γιατί ο αριθμός των checkbox δεν είναι προκαθορισμένος και δεν ξέρω πώς θα τον συνδέσω με το καινούριο model

  •  14-05-2013, 15:35 72593 σε απάντηση της 72588

    Απ: Many to many relationship

    Χρειάζεσαι παράδειγμα σε αυτό που είπε ο xabikos σχετικά με τα many to many relations και το EF;

    Βασικά θα πρέπει να το πάρουμε λίγο πιο πριν. Πως δουλεύεις με το EF. Δηλαδή το χρησιμοποιείς σαν Model First, Database First ή Code First. Αν είναι το πρώτο και το τρίτο τότε μπορείς να φτιάξεις δύο entities που το ένα να αναφέρεται στο άλλο σαν collection. Το EF θα καταλάβει ότι είναι σχέση πολλά προς πολλά και όταν θα πάει να δημιουργήσει την βάση θα φτιάξει έναν τρίτο πίνακα που θα κάνει αυτό που κάνεις ήδη εσύ. Το σημείο όμως αναφοράς είναι πως για αυτόν τον τρίτο πίνακα που συνδέει τους άλλους δεν θα έχεις entity στο model σου οπότε είναι πιο απλά τα πράγματα. Σου έχω ένα link από ένα παράδειγμα που χρησιμοποιεί την τεχνική Code First για να καταλάβεις τι κάνει το EF. http://odetocode.com/blogs/scott/archive/2012/06/13/many-to-many-relationships-with-ef.aspx

    Τώρα αν το πας με το Database First επειδή αυτόν τον πίνακα τον έχεις ήδη δημιουργήσει στην βάση και έχεις χτίσει το Domain Model από την βάση (για αυτό και λέγεται Database First) τότε όπως καταλαβαίνεις θα σου φέρει μέσα στο model και τον τρίτο πίνακα. Δεν γνωρίζω την διαδικασία και το εάν γίνεται, να μπορείς να διαγράψεις αυτόν τον συνδετικό πίνακα, ίσως κάποιος άλλος να μπορούσε να απαντήσει και να το μάθαινα και εγώ.

     

  •  15-05-2013, 03:22 72595 σε απάντηση της 72593

    Απ: Many to many relationship

    Σε σύνδεση με το προηγούμενο Post για την τεχνική Database First, έχω αυτό το link http://blogs.objectsharp.com/post/2011/01/28/Entity-Framework-Many-to-Many-Relationships.aspx

    Οπότε γίνεται και στο Database First.

     

  •  18-05-2013, 01:43 72600 σε απάντηση της 72593

    Απ: Many to many relationship

    George Parissis:

    Τώρα αν το πας με το Database First επειδή αυτόν τον πίνακα τον έχεις ήδη δημιουργήσει στην βάση και έχεις χτίσει το Domain Model από την βάση (για αυτό και λέγεται Database First) τότε όπως καταλαβαίνεις θα σου φέρει μέσα στο model και τον τρίτο πίνακα. Δεν γνωρίζω την διαδικασία και το εάν γίνεται, να μπορείς να διαγράψεις αυτόν τον συνδετικό πίνακα, ίσως κάποιος άλλος να μπορούσε να απαντήσει και να το μάθαινα και εγώ.

    Αν και έχω αρκετό καιρό να παίξω με EF, θυμάμαι ότι όταν ο συνδετικός πίνακας είναι pure (έχει μόνο τα δύο πεδία που είναι απαραίτητα για τη σχέση N-N) τότε δεν τον βάζει μέσα στο μοντέλο. Αν όμως έχει extra πεδία, σημαίνει ότι τα χρειάζεσαι και τότε τον βάζει στο μοντέλο.

     


    Vir prudens non contra ventum mingit
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems