none
Come normalizzare due tabelle RRS feed

  • Domanda

  • Questo è il mio problema: ho una tabella chiamata "Post" con le seguenti colonne: Id, Title, Text.
    Ho un'altra tabella chiamata "Person" con le seguenti colonne: Id, FirstName, LastName, PostWritten.
    La colonna PostWritten la considero come colonna di foreignKey che riferisce alla colonna Id della tabella Post.
    Quindi, correggetemi se sbaglio, sono di fronte ad una relazione UNO A MOLTI.

    Tuttavia ho la necessità di apportare una modifica alla tabella "Person", cioè aggiungere un ulteriore foreignKey ovvero PostUpdated. Quindi, adesso, la tabella "Person" contiene le seguenti colonne: Id, FirstName, LastName, PostWritten e PostUpdated.

    In futuro la tabella "Person" conterrà ulteriori colonne: PostModified, PostRead... quindi 4 oppure 5 relazioni, tutte con riferimento alla colonna Id della tabella "Post".

    Il problema è che Entity Framework vuole una sola relazione ( mi sembra in virtù del pattern Identity Map).

    La domanda è la seguente come posso normalizzare le due tabelle?

    venerdì 26 luglio 2013 07:48

Risposte

  • Ciao,

    secondo me, il tuo object model è corretto. Lato "Post" hai:

    • "Post" ha il riferimento alla "Person" che l'ha creato.
    • "Post" ha il riferimento alla "Person" che l'ha aggiornato.

    Lato "Person" hai:

    • "Person" ha l'elenco dei "Post" che ha aggiornato.
    • "Person" ha l'elenco dei "Post" che ha creato.

    Quindi hai due relazioni Uno a Molti.

    il discorso sull'Identity Map che fa EF è corretto, perché se hai due post che sono stati creati e aggiornati dalla stessa persona, in memoria è corretto che tu abbia le due istanze di tipo "Post" e la sola istanza di tipo "Person". Quando poi persisterai l'object model, sarà l'OR/M che si preoccuperà di gestire la situazione per mettere d'accordo il modello relazionale.

    La situazione Molti a Molti l'avresti se tu volessi tenere la storia delle modifiche al post, perché in quel caso avresti:

    • "Post" può essere modificato da più "Person".
    • "Person" può modificare più "Post".

    per gestire questa situazione, lato "Post" ti servirebbe una ICollection di "Person", che lato DB ti si tradurebbe in una tabella di cross reference del tipo "PersonModifiedPost".

    HTH,


    Alberto Dallagiacoma
    My Italian Blog: http://blogs.ugidotnet.org/alby
    Twitter: http://twitter.com/albertodall
    DotDotNet - User Group .NET Emilia Romagna: http://www.dotdotnet.org


    martedì 30 luglio 2013 09:05

Tutte le risposte

  • Ciao pedatt80,

    a mio parere le due tabelle sono già normalizzate. Il tuo problema è come modellarle in EF? Quale versione stai usando?


    Se questo post risponde alla tua domanda ricorda di contrassegnarlo come risposta. In questo modo aiuterai altri utenti che hanno lo stesso problema a trovare la risposta più velocemente. Grazie.

    venerdì 26 luglio 2013 15:28
  • Attualmente sto usando VS2012 con EF5.0 in Code First. La situazione a cui sono giunto credo trattasi di una "Relazione multipla". Questo è il mio codice:

    public class Post
        {
            public int Id { get; set; }
            public string Title { get; set; }
            public virtual Person CreatedBy { get; set; }
            public virtual Person UpdatedBy { get; set; }
        }
    
        public class Person
        {
            public int Id { get; set; }
            public string Name { get; set; }
            [InverseProperty("CreatedBy")]
            public ICollection<Post> PostsWritten { get; set; }
            [InverseProperty("UpdatedBy")]
            public ICollection<Post> PostsUpdated { get; set; }
        }
    
        public class MyContext : DbContext
        {
            public DbSet<Post> Posts { get; set; }
            public DbSet<Person> People { get; set; }
        }

    Ma Entity Framework implementa il pattern Identity Map, ciò vuol dire che nel DbContext non possono coesistere due istanze diverse di Person che abbiano la stessa chiave primaria.

    Inoltre, il mio dubbio è il seguente, se le relazioni possono essere:

    1) Uno a Uno;

    2) Uno a Molti;

    3) Molti a Molti;

    Quella da me implementata, che inizialmente era Uno a Molti, adesso in cosa si è trasformata?

    Quindi, ho pensato di "normalizzare" il tutto, magari passando ad una relazione Molti a Molti come suggerito qui: http://dba.stackexchange.com/questions/6519/two-relationships-to-same-table

    • Modificato piedatt80 lunedì 29 luglio 2013 13:47 Modifica
    venerdì 26 luglio 2013 16:49
  • Nessuna novità?

    Per adesso, i miei sono solo dubbi ed in incertezze.

    lunedì 29 luglio 2013 13:47
  • Ciao,

    secondo me, il tuo object model è corretto. Lato "Post" hai:

    • "Post" ha il riferimento alla "Person" che l'ha creato.
    • "Post" ha il riferimento alla "Person" che l'ha aggiornato.

    Lato "Person" hai:

    • "Person" ha l'elenco dei "Post" che ha aggiornato.
    • "Person" ha l'elenco dei "Post" che ha creato.

    Quindi hai due relazioni Uno a Molti.

    il discorso sull'Identity Map che fa EF è corretto, perché se hai due post che sono stati creati e aggiornati dalla stessa persona, in memoria è corretto che tu abbia le due istanze di tipo "Post" e la sola istanza di tipo "Person". Quando poi persisterai l'object model, sarà l'OR/M che si preoccuperà di gestire la situazione per mettere d'accordo il modello relazionale.

    La situazione Molti a Molti l'avresti se tu volessi tenere la storia delle modifiche al post, perché in quel caso avresti:

    • "Post" può essere modificato da più "Person".
    • "Person" può modificare più "Post".

    per gestire questa situazione, lato "Post" ti servirebbe una ICollection di "Person", che lato DB ti si tradurebbe in una tabella di cross reference del tipo "PersonModifiedPost".

    HTH,


    Alberto Dallagiacoma
    My Italian Blog: http://blogs.ugidotnet.org/alby
    Twitter: http://twitter.com/albertodall
    DotDotNet - User Group .NET Emilia Romagna: http://www.dotdotnet.org


    martedì 30 luglio 2013 09:05
  • Ok. Grazie per la spiegazione.
    mercoledì 7 agosto 2013 06:57