Comment gérer ces deux modèles dans une première approche de code avec Entity Framework 7?

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

Question

Problème

Je suis en train de coder la preuve de concept ASP.NET 5 MVC6 qui simulera une bibliothèque. J'utilise CTP6 et beta3.

Comment définir leur relation dans Entity Framework 7 en utilisant l’approche code premier?

Les étagères et les livres nécessitent une table de jointure. Comme je le vois, cette application va considérer une étagère à la fois et les livres sur cette auto. En d'autres termes, une étagère a une relation un à plusieurs avec des livres.

Des modèles

Modèle d'étagère:

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; }

}

Modèle de livre:

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; }

}

Objectif

J'aimerais implémenter quelque chose comme ceci dans ASP.NET 5. Etant donné que TPH et d'autres fonctionnalités ne sont pas encore implémentées dans EF7, suis-je sur la bonne voie?

En d'autres termes, je pense à ce qui suit:

  • ShelfBookViewModel (après tout, j'ai besoin d'un modèle de vue pour montrer une étagère et les livres, ou le livre et pouvoir revenir à l'étagère). Je vais probablement juste l'appeler ShelfBook. Cela semble être la mauvaise approche.
  • Je préférerais que EF7 sache que j'ai une jointure et crée des modèles de vue pour des préoccupations distinctes. Sinon, cela constitue une violation des pratiques du code SOLID. Quelque chose comme donné ci-dessous (à partir du lien plus tôt).
  • Les tables de jointure n'ont pas encore été implémentées dans EF7 et je demande en vain?

Je n'ai pas pu obtenir les éléments suivants pour fonctionner comme indiqué ci-dessous:

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

Merci d'avoir pris le temps de lire ma question. J'espère que d'autres trouveront cela utile.

Réponse populaire

Pour répondre à votre question sur plusieurs-plusieurs, vous devez définir votre mappage comme suit (et, nécessairement, mettre à jour vos classes de modèle):

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"); 
       });

ce qui vous obligerait à ajouter un ICollection<Shelf> Shelves { get; set; } Book . Mais si vous le faisiez, vous auriez alors le texte suivant ( voici ma version MCVE de votre exemple):

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; }
}

de toute façon, vous n’auriez plus besoin du mappage, puisque EF générerait pour vous toutes les relations par convention, y compris la table de jointure qui ne serait visible que dans la base de données elle-même.

Cependant, d'après vos modèles de classes et votre discussion à ce sujet, il apparaît que vous n'avez vraiment besoin que de un à plusieurs. Dans ce cas, vous devez accepter la réponse de Pynt et ignorer la mienne.

MODIFIER

Comme l'a souligné Gert Arnold dans les commentaires, EF7 ne prend actuellement pas (plus?) En charge les tables de jointure générées, ce qui signifie que nous devrons rouler les nôtres, ce qui est sans doute mieux .

Voici une façon dont je pense que je pourrais faire les miennes, simple, joindre des tables à partir de maintenant, si EF ne les ferait plus pour moi (avertissement - j'essaie juste de boucler la boucle sur cette question ... prendre la peine d’essayer cela dans un compilateur, donc 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; }
}


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi