Simulate the same SQL in the Entity Framework with Linq and Lambda?

5

Having this data model I want to generate a SQL in the Entity Framework with < a href="http://msdn.microsoft.com/en-us/library/bb425822.aspx"> Linq and

asked by anonymous 03.07.2014 / 17:41

1 answer

4

To generate this type of SQL you must use the GroupJoin > with SelectMany / a> to have the same effect as the requested SQL. The examples below prove the generation of the same SQL, note:

Linq

using (ObjEntities cx = new ObjEntities())
{
    var resultLinq = (from pessoa in cx.Pessoa
                      join pessoapai in cx.Pessoa on pessoa.PessoaPaiId equals pessoapai.PessoaId into Pai
                      from P in Pai.DefaultIfEmpty()
                      join pessoamae in cx.Pessoa on pessoa.PessoaMaeId equals pessoamae.PessoaId into Mae
                      from M in Mae.DefaultIfEmpty()
                      select new
                      {
                          pessoa.PessoaId,
                          pessoa.Nome,
                          pessoa.PessoaPaiId,
                          NomePai = P.Nome,
                          pessoa.PessoaMaeId,
                          NomeMae = M.Nome
                      })
                      .ToList();

}

Lambda:

using (ObjEntities cx = new ObjEntities())
{
    var resultLambda = cx.Pessoa
        .GroupJoin(cx.Pessoa, pessoa => pessoa.PessoaPaiId, pessoapai => pessoapai.PessoaId, (pessoa, pessoapai) => new { pessoa, pessoapai })
        .SelectMany(a => a.pessoapai.DefaultIfEmpty(), (c, d) => new
        {
            c.pessoa.PessoaId,
            c.pessoa.Nome,                        
            NomePai = d.Nome,
            c.pessoa.PessoaPaiId, 
            c.pessoa.PessoaMaeId
        })
        .GroupJoin(cx.Pessoa, pessoa => pessoa.PessoaMaeId, pessoamae => pessoamae.PessoaId, (pessoa, pessoamae) => new { pessoa, pessoamae }) 
        .SelectMany(b => b.pessoamae.DefaultIfEmpty(), (e, f) => new {
            e.pessoa.PessoaId, 
            e.pessoa.Nome, 
            e.pessoa.PessoaPaiId, 
            NomePai = e.pessoa.NomePai,
            e.pessoa.PessoaMaeId,
            NomeMae = f.Nome
        })
        .ToList();          
}

The generation of SQL of the two types of coding style is the same as the question:

SELECT 
[Extent1].[PessoaId] AS [PessoaId], 
[Extent1].[Nome] AS [Nome], 
[Extent1].[PessoaPaiId] AS [PessoaPaiId], 
[Extent2].[Nome] AS [Nome1], 
[Extent1].[PessoaMaeId] AS [PessoaMaeId], 
[Extent3].[Nome] AS [Nome2]
FROM   [dbo].[Pessoa] AS [Extent1]
LEFT OUTER JOIN [dbo].[Pessoa] AS [Extent2] ON [Extent1].[PessoaPaiId] = [Extent2].[PessoaId]
LEFT OUTER JOIN [dbo].[Pessoa] AS [Extent3] ON [Extent1].[PessoaMaeId] = [Extent3].[PessoaId]

Debug

References:

03.07.2014 / 17:41