Middle
Como implementar uma relação muitos-para-muitos em C#?
sobes.tech IA
Resposta da IA
A relação de "muitos para muitos" em C# usando Entity Framework Core geralmente é implementada através de uma tabela intermédia (de ligação).
Etapas de implementação:
- Criar entidades: Defina duas classes de entidades para ambos os lados da relação.
- Criar uma entidade intermédia: Crie uma classe de entidade separada para a tabela intermédia. Esta entidade conterá chaves estrangeiras para ambas as entidades relacionadas e, opcionalmente, propriedades adicionais que descrevem a própria relação.
- Configurar relações no DbContext: No método
OnModelCreatingdo seuDbContext, configure as relações entre a entidade intermédia e as duas entidades principais. Use os métodosHasMany,WithMany,UsingEntitypara configurar explicitamente a tabela intermédia.
Exemplo:
Suponha que você tenha as entidades Book e Author, e que um livro possa ser escrito por vários autores, e um autor possa escrever vários livros.
// Entidade 1
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public ICollection<BookAuthor> BookAuthors { get; set; }
}
// Entidade 2
public class Author
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<BookAuthor> BookAuthors { get; set; }
}
// Entidade intermédia
public class BookAuthor
{
public int BookId { get; set; }
public Book Book { get; set; }
public int AuthorId { get; set; }
public Author Author { get; set; }
// Propriedades adicionais, por exemplo, o papel do autor no livro
public string Role { get; set; }
}
// Configuração no DbContext
public class ApplicationDbContext : DbContext
{
public DbSet<Book> Books { get; set; }
public DbSet<Author> Authors { get; set; }
public DbSet<BookAuthor> BookAuthors { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<BookAuthor>()
.HasKey(ba => new { ba.BookId, ba.AuthorId }); // Chave primária composta
modelBuilder.Entity<BookAuthor>()
.HasOne(ba => ba.Book)
.WithMany(b => b.BookAuthors)
.HasForeignKey(ba => ba.BookId);
modelBuilder.Entity<BookAuthor>()
.HasOne(ba => ba.Author)
.WithMany(a => a.BookAuthors)
.HasForeignKey(ba => ba.AuthorId);
}
}
Utilização:
// Adicionando um livro e um autor
var book = new Book { Title = "Meu Livro Incrível" };
var author = new Author { Name = "Jane Doe" };
var bookAuthor = new BookAuthor {
Book = book,
Author = author,
Role = "Autor Principal"
};
_context.Books.Add(book);
_context.Authors.Add(author);
_context.BookAuthors.Add(bookAuthor);
_context.SaveChanges();
// Obtendo o livro com autores
var bookWithAuthors = _context.Books
.Include(b => b.BookAuthors)
.ThenInclude(ba => ba.Author)
.FirstOrDefault(b => b.Id == book.Id);
// Obtendo o autor com livros
var authorWithBooks = _context.Authors
.Include(a => a.BookAuthors)
.ThenInclude(ba => ba.Book)
.FirstOrDefault(a => a.Id == author.Id);
Esta abordagem com uma entidade intermediária é recomendada no EF Core, pois permite gerenciar de forma flexível dados adicionais sobre a relação. Em casos mais simples, o EF Core pode criar automaticamente uma tabela intermediária oculta, mas definir explicitamente a entidade oferece maior controle.