Come gestire questi due modelli nel primo approccio al codice utilizzando Entity Framework 7?

asp.net-core c# entity-framework entity-framework-core jointable

Domanda

Problema

Sto codificando la prova del concetto ASP.NET 5 MVC6 che simulerà una libreria. Sto usando CTP6 e beta3.

Come definire la loro relazione in Entity Framework 7 usando l'approccio code first?

Scaffale e libri hanno bisogno di una tabella di join. Per come la vedo io, questa applicazione prenderà in considerazione uno scaffale alla volta e i libri su quel sé. In altre parole, uno scaffale ha una relazione uno a molti con i libri.

Modelli

Modello di scaffale:

public class Shelf
{
    public int ShelfId { get; set; }

    public string ShelfName { get; set; }

    public ShelfType MyProperty { get; set; }

    public virtual List<Book> Books { get; set; }

    public DateTime Created { get; set; }

    public string CreatedBy { get; set; }

    public DateTime Updated { get; set; }

    public string UpdatedBy { get; set; }

}

Modello di libro:

public class Book
{
    public int BookId { get; set; }

    public string BookName { get; set; }

    public string BookAuthor { get; set; }

    public string BookGenre { get; set; }

    public DateTime BookPublishedDate { get; set; }

    public string Description { get; set; }

    public DateTime Created { get; set; }

    public string CreatedBy { get; set; }

    public DateTime Updated { get; set; }

    public string UpdatedBy { get; set; }

}

Obbiettivo

Vorrei implementare qualcosa di simile a questo in ASP.NET 5. Poiché TPH e altre caratteristiche non sono ancora attuate in EF7, io sono sulla strada giusta?

In altre parole, sto pensando quanto segue:

  • ShelfBookViewModel (dopotutto ho bisogno di un modello di visualizzazione per mostrare uno scaffale e i libri, o il libro ed essere in grado di tornare allo scaffale). Probabilmente lo chiamerò solo ShelfBook. Questo sembra essere l'approccio sbagliato.
  • Preferirei che l'EF7 fosse in grado di capire di avere un join e di creare viewmodels per preoccupazioni separate. In caso contrario, si tratta di una violazione delle pratiche di codice SOLID. Qualcosa di simile indicato di seguito (dal link precedente).
  • Le tabelle di join non sono ancora state implementate in EF7 e sto chiedendo invano?

Non sono stato in grado di ottenere quanto segue per funzionare come mostrato di seguito:

 modelBuilder.Entity<Shelf>() 
            .HasMany(p => p.Shelfs) 
            .WithMany(t => t.Books) 
            .Map(mc => 
               { 
                   mc.ToTable("ShelfJoinBook"); 
                   mc.MapLeftKey("ShelfId"); 
                   mc.MapRightKey("BookId"); 
               });

Grazie per il tuo tempo nel leggere la mia domanda. Spero che altri lo trovino utile.

Risposta popolare

Per rispondere alla tua domanda su molti-a-molti, dovresti definire la tua mappatura come segue (e, necessariamente, aggiornare le tue classi modello):

modelBuilder.Entity<Shelf>() 
    .HasMany(p => p.Books) 
    .WithMany(t => t.Shelves) // doesn't exist 
    .Map(mc => 
       { 
           mc.ToTable("BookShelves"); 
           mc.MapLeftKey("ShelfId"); 
           mc.MapRightKey("BookId"); 
       });

che richiederebbe l'aggiunta di uno ICollection<Shelf> Shelves { get; set; } per Book . Ma, se lo facessi, avresti il ​​seguente (questa è la mia versione MCVE del tuo esempio):

public class Shelf
{
    public int ShelfId { get; set; }
    public virtual ICollection<Book> Books { get; set; }
}

public class Book
{
    public int BookId { get; set; }
    public virtual ICollection<Shelf> Shelves { get; set; }
}

e quindi non avresti più bisogno della mappatura comunque, poiché EF genererebbe tutte le relazioni per te per convenzione, inclusa la tabella di join che sarebbe visibile solo nel database stesso.

Tuttavia - dalle tue attuali classi modello e dalle tue discussioni intorno a loro - sembra che tu abbia davvero bisogno solo di uno a molti, nel qual caso dovresti accettare la risposta di Pynt e ignorare il mio.

MODIFICARE

Come sottolineato da Gert Arnold nei commenti, EF7 attualmente non supporta (non più?) Le tabelle di join generate, il che significa che dovremo eseguire il rollover, il che probabilmente è comunque migliore .

Ecco un modo in cui penso che potrei fare da solo, semplice, unire i tavoli da ora in poi, se EF non li farà più per me (attenzione - sto solo cercando di chiudere il ciclo su questo problema ... Non sono preoccuparsi di provare questo in un compilatore, quindi YMMV):

public class Shelf
{
    public int ShelfId { get; set; }
    public virtual ICollection<BookShelf> BookShelves { get; set; }
    public virtual IQueryable<Book> Books
    {
        get
        {
            return BookShelves.Where(s => s.ShelfId == ShelfId)
                              .Select(s => s.Book);
        }
    }
}

public class Book
{
    public int BookId { get; set; }
    public virtual ICollection<BookShelf> BookShelves { get; set; }
    public virtual IQueryable<Shelf> Shelves
    {
        get
        {
            return BookShelves.Where(s => s.BookId == BookId)
                              .Select(s => s.Shelf);
        }
    }
}

public class BookShelf
{
    [Key]
    public int BookId { get; set; }
    [ForeignKey("BookId")]
    public Book Book { get; set; }
    [Key]
    public int ShelfId { get; set; }
    [ForeignKey("ShelfId")]
    public Shelf Shelf { get; set; }
}


Related

Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow