Entity Framework - Consulta em Many to Many

22/12/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:
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
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:
Titulo,  Autor
Livro 1, Autor 1
Livro 1, Autor 2
Livro 2, Autor 2
Livro 3, Autor 1
Livro 3, Autor 3



Tentativa 1:
       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:
 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.

[/code]
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
[/code]

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?

Marcelo Rodrigues