Array
(
)

Entity Framework - Consulta em Many to Many

Marcelo Rodrigues
   - 22 dez 2011

Pessoal,
estou com um problema que não consigo resolver.
Resolvi mapear duas tabelas com um relecionamento Many to Many e não estou conseguindo fazer uma consulta correta.
As tabelas são bem simples:
#Código

Livro (Id_livro int , Titulo varchar(255))

Autor (id_Autor int , Nome varchar(255))

Autor_Livro (id_livro int , Id_autor int )


Ao criar o modelo, ele mapeia em duas Classes (Livro e Autor). A tabela Autor_Livro não é criada, mas sim é mapeada como um relacionamento Many to Many entre Livro e Autor.
O problema: Fazer uma consulta que relacione o titulo do livro e o seus autores
Em SQL seria um join simples
#Código
SELECT     Livro.Titulo, Autor.Nome 
FROM         Autor INNER JOIN Autor_livro ON Autor.Id_autor = Autor_livro.id_autor
INNER JOIN Livro ON Autor_livro.Id_livro = Livro.id_livro
ORDER BY Livro.Titulo

Que teria um resultado como por exemplo:
#Código
Titulo,  Autor
Livro 1, Autor 1
Livro 1, Autor 2
Livro 2, Autor 2
Livro 3, Autor 1
Livro 3, Autor 3


Tentativa 1:
#Código
       Dim ct As New MyModel
       Dim lista = From L In ct.Livro
                    From A In ct.Autor
                    Order By L.Titulo
                    Select L.Titulo, A.Nome
        GridView1.DataSource = lista
        GridView1.DataBind()

Resultado: gera um produto cartesiano (a consulta SQL gerada faz um cross join).
Tentativa 2:
#Código
 Dim ct As New MyModel
 Dim lista = From L In ct.Livro
                    From A In ct.Autor
                    Where A.Livro.Contains(L) Order By L.Titulo
                    Select L.Titulo, A.Nome
        GridView1.DataSource = lista
        GridView1.DataBind()

Resultado: faz a consulta correta mas gera um SQL muito ruim.
[/tagcod]
SELECT [Extent1].[id_livro] AS [id_livro], [Extent1].[Titulo] AS [Titulo], [Extent2].[Nome] AS [Nome]
FROM [dbo].[Livro] AS [Extent1]
CROSS JOIN [dbo].[Autor] AS [Extent2]
WHERE EXISTS (SELECT
1 AS [C1]
FROM (SELECT
[Autor_livro].[Id_livro] AS [Id_livro],
[Autor_livro].[id_autor] AS [id_autor]
FROM [dbo].[Autor_livro] AS [Autor_livro]) AS [Extent3]
WHERE ([Extent2].[Id_autor] = [Extent3].[id_autor]) AND ([Extent3].[Id_livro] = [Extent1].[id_livro])
)
ORDER BY [Extent1].[Titulo] ASC
[/tagcod]
Tentativa 3: usar a clausula JOIN no Linq. Não consegui (não há chaves a relacionar), já que não existe a classe Titulo_Autor, pois o mapeamento é Many to Many.
Desafio: fazer a consulta LINQ em entidades com relacionamento Many to Many e que use Inner joins.
Alguém pode dar uma ajuda?