开发者

Linq - Group by multiple tables with multiple returns

开发者 https://www.devze.com 2023-03-26 04:29 出处:网络
Using Linq to Sql how do I group the following table (entidadeProdutosFornecedores) and return fields from N tables ?

Using Linq to Sql how do I group the following table (entidadeProdutosFornecedores) and return fields from N tables ?

Original Query in SQL

SELECT  @NM_VALOR1      = MAX(ProdutosFornecedores.NM_PRECO_REPOSICAO),
                @NM_VALOR2      = MAX(ProdutosFornecedores.ID_MOEDAS_REPOSICAO),
                @ID_IMPOSTOSDESTINOS    = MAX(Fornecedores.ID_IMPOSTOSDESTINOS),
                @ID_IMPOSTOSCONFIG  = MAX(ProdutosFornecedores.ID_IMPOSTOSCONFIG),
                @ID_TABELANCMS      = MAX(ProdutosFornecedores.ID_TABELANCMS),
                @ID_FORNECEDORES    = MAX(Fornecedores.ID_FORNECEDORES),
                @CD_UF_BASE     = MAX(UnidadesFederacao.CD_UNIDADEFEDERACAO)
              FROM  ProdutosFornecedores
                INNER JOIN Fornecedores     ON Fornecedores.ID_FORNECEDORES       = ProdutosFornecedores.ID_FORNECEDORES
                INNER JOIN Municipios       ON Municipios.ID_MUNICIPIOS       = Fornecedores.ID_MUNICIPIOS
                INNER JOIN UnidadesFederacao    ON UnidadesFederacao.ID_UNIDADESFEDERACAO = Municipios.ID_UNIDADESFEDERACAO
             WHERE  ProdutosFornecedores.ID_PRODUTOS        = CAST(@CD_OBJETO1 AS INT)  AND
                ProdutosFornecedores.ID_PRODUTOSCONFIGPRECOS    = CAST(@CD_OBJETO2 AS INT)  AND
                ProdutosFornecedores.FG_STATUS          = 1
            GROUP BY
                ProdutosFornecedores.ID_PRODUTOS,
                ProdutosFornecedores.ID_PRODUTOSCONFIGPRECOS

Query converted to Linq

var prodForn2 = from entidadeProdutosFornecedores in ERPDAOManager.GetTable<ProdutosFornecedores>()
                                                    //Inner Join with Fornecedores
                                                    join entidadeFornecedores in ERPDAOManager.GetTable<Fornecedores>()
                                                         on entidadeProdutosFornecedores.ID_FORNECEDORES equals entidadeFornecedores.ID into tempFornecedores
                                                    from fornecedores in tempFornecedores
                                                    //Inner Join with Municipios
                                                    join entidadeMuncipios in ERPDAOManager.GetTable<Municipios>()
                                                        on fornecedores.ID_MUNICIPIOS equals entidadeMuncipios.ID into tempMunicipios
                                                    from municipios in tempMunicipios
                                                    //Inner Join with UnidadesFederacao
                                                    join entidadeUnidadesFederacao in ERPDAOManager.GetTable<UnidadesFederacao>()
                                                        on municipios.ID_UNIDADESFEDERACAO equals entidadeUnidadesFederacao.ID into tempUnidadesFederacao
                                                    from unidadesFederacao in tempUnidadesFederacao
                                                    //Filters
                                                    where entidadeProdutosFornecedores.ID_PRODUTOS == Convert.ToInt32(objEsquemasCalculoRegras.CD_OBJETO1) &&
                                                          entidadeProdutosFornecedores.ID_PRODUTOSCONFIGPRECOS == Convert.ToInt32(objEsquemasCalculoRegras.CD_OBJETO2) &&
                                                          entidadeProdutosFornecedores.FG_STATUS == true
                                                    group entidadeProdutosFornecedores by new { entidadeProdutosFornecedores.ID_PRODUTOS, entidadeProdutosFornecedores.ID_PRODUTOSCONFIGPRECOS } into produtosFornec开发者_运维知识库edores
                                                    select new
                                                    {
                                                        NM_PRECO_REPOSICAO = (decimal)produtosFornecedores.Max(item => item.NM_PRECO_REPOSICAO),
                                                        ID_MOEDAS_REPOSICAO = (int)produtosFornecedores.Max(item => item.ID_MOEDAS_REPOSICAO),
                                                        ID_IMPOSTOSDESTINOS = (int)fornecedores.ID_IMPOSTOSDESTINOS, //Error: The name fornecedores does not exist in the current context
                                                        ID_IMPOSTOSCONFIG = (int)produtosFornecedores.Max(item => item.ID_IMPOSTOSCONFIG),
                                                        ID_TABELANCMS = (int)produtosFornecedores.Max(item => item.ID_TABELANCMS),
                                                        ID_FORNECEDORES = (int)fornecedores.ID, //Error: The name fornecedores does not exist in the current context
                                                        CD_UF_BASE = (string)unidadesFederacao.CD_UNIDADEFEDERACAO //Error: The name unidadesFederacao does not exist in the current context
                                                    };


The issue you're getting with your query is that you're trying to access "from" variables after the "group by" which you can't do. In order to get these variables they must be either (1) kept outside of the grouping or (2) made into part of the grouping itself.

(1)

var prodForn2 =
    from produtosFornecedores in ERPDAOManager.GetTable<ProdutosFornecedores>()
    join fornecedores in ERPDAOManager.GetTable<Fornecedores>()
        on produtosFornecedores.ID_FORNECEDORES equals fornecedores.ID
    join municipios in ERPDAOManager.GetTable<Municipios>()
        on fornecedores.ID_MUNICIPIOS equals municipios.ID
    join unidadesFederacao in ERPDAOManager.GetTable<UnidadesFederacao>()
        on municipios.ID_UNIDADESFEDERACAO equals unidadesFederacao.ID
    where produtosFornecedores.ID_PRODUTOS ==
        Convert.ToInt32(objEsquemasCalculoRegras.CD_OBJETO1)
    where produtosFornecedores.ID_PRODUTOSCONFIGPRECOS ==
        Convert.ToInt32(objEsquemasCalculoRegras.CD_OBJETO2)
    where produtosFornecedores.FG_STATUS == true
    let ID_IMPOSTOSDESTINOS = (int)fornecedores.ID_IMPOSTOSDESTINOS
    let ID_FORNECEDORES = (int)fornecedores.ID
    let CD_UF_BASE = (string)unidadesFederacao.CD_UNIDADEFEDERACAO
    group produtosFornecedores by new
    {
        ID_IMPOSTOSDESTINOS,
        ID_FORNECEDORES,
        CD_UF_BASE,
    } into gpfs1
    select new
    {
        gpfs1.Key.ID_IMPOSTOSDESTINOS,
        gpfs1.Key.ID_FORNECEDORES,
        gpfs1.Key.CD_UF_BASE,
        PRODUTOSFORNECEDORES =
            from pfs1 in gpfs1
            group pfs1 by new
            {
                pfs1.ID_PRODUTOS,
                pfs1.ID_PRODUTOSCONFIGPRECOS
            } into gpfs2
            select new
            {
                NM_PRECO_REPOSICAO = (decimal)gpfs2
                    .Max(item => item.NM_PRECO_REPOSICAO),
                ID_MOEDAS_REPOSICAO = (int)gpfs2
                    .Max(item => item.ID_MOEDAS_REPOSICAO),
                ID_IMPOSTOSCONFIG = (int)gpfs2
                    .Max(item => item.ID_IMPOSTOSCONFIG),
                ID_TABELANCMS = (int)gpfs2
                    .Max(item => item.ID_TABELANCMS),
            },
    };

(2)

var prodForn2 =
    from produtosFornecedores in ERPDAOManager.GetTable<ProdutosFornecedores>()
    join fornecedores in ERPDAOManager.GetTable<Fornecedores>()
        on produtosFornecedores.ID_FORNECEDORES equals fornecedores.ID
    join municipios in ERPDAOManager.GetTable<Municipios>()
        on fornecedores.ID_MUNICIPIOS equals municipios.ID
    join unidadesFederacao in ERPDAOManager.GetTable<UnidadesFederacao>()
        on municipios.ID_UNIDADESFEDERACAO equals unidadesFederacao.ID
    where produtosFornecedores.ID_PRODUTOS ==
        Convert.ToInt32(objEsquemasCalculoRegras.CD_OBJETO1)
    where produtosFornecedores.ID_PRODUTOSCONFIGPRECOS ==
        Convert.ToInt32(objEsquemasCalculoRegras.CD_OBJETO2)
    where produtosFornecedores.FG_STATUS == true
    let ID_IMPOSTOSDESTINOS = (int)fornecedores.ID_IMPOSTOSDESTINOS
    let ID_FORNECEDORES = (int)fornecedores.ID
    let CD_UF_BASE = (string)unidadesFederacao.CD_UNIDADEFEDERACAO
    group produtosFornecedores by new
    {
        ID_IMPOSTOSDESTINOS,
        ID_FORNECEDORES,
        CD_UF_BASE,
        produtosFornecedores.ID_PRODUTOS,
        produtosFornecedores.ID_PRODUTOSCONFIGPRECOS,
    } into gpfs
    select new
    {
        gpfs.Key.ID_IMPOSTOSDESTINOS,
        gpfs.Key.ID_FORNECEDORES,
        gpfs.Key.CD_UF_BASE,
        NM_PRECO_REPOSICAO = (decimal)gpfs.Max(item => item.NM_PRECO_REPOSICAO),
        ID_MOEDAS_REPOSICAO = (int)gpfs.Max(item => item.ID_MOEDAS_REPOSICAO),
        ID_IMPOSTOSCONFIG = (int)gpfs.Max(item => item.ID_IMPOSTOSCONFIG),
        ID_TABELANCMS = (int)gpfs.Max(item => item.ID_TABELANCMS),
    };

Give each of these a go and see which suits your needs better.

You may also find that performance is an issue with grouping and the multiple max queries, so it might be worth your while bringing the records into memory before grouping the results.

var prodForn2_1 =
    from produtosFornecedores in ERPDAOManager.GetTable<ProdutosFornecedores>()
    join fornecedores in ERPDAOManager.GetTable<Fornecedores>()
        on produtosFornecedores.ID_FORNECEDORES equals fornecedores.ID
    join municipios in ERPDAOManager.GetTable<Municipios>()
        on fornecedores.ID_MUNICIPIOS equals municipios.ID
    join unidadesFederacao in ERPDAOManager.GetTable<UnidadesFederacao>()
        on municipios.ID_UNIDADESFEDERACAO equals unidadesFederacao.ID
    where produtosFornecedores.ID_PRODUTOS ==
        Convert.ToInt32(objEsquemasCalculoRegras.CD_OBJETO1)
    where produtosFornecedores.ID_PRODUTOSCONFIGPRECOS ==
        Convert.ToInt32(objEsquemasCalculoRegras.CD_OBJETO2)
    where produtosFornecedores.FG_STATUS == true
    let ID_IMPOSTOSDESTINOS = (int)fornecedores.ID_IMPOSTOSDESTINOS
    let ID_FORNECEDORES = (int)fornecedores.ID
    let CD_UF_BASE = (string)unidadesFederacao.CD_UNIDADEFEDERACAO
    select new
    {
        ID_IMPOSTOSDESTINOS = (int)fornecedores.ID_IMPOSTOSDESTINOS,
        ID_FORNECEDORES = (int)fornecedores.ID,
        CD_UF_BASE = (string)unidadesFederacao.CD_UNIDADEFEDERACAO,
        ID_PRODUTOS = produtosFornecedores.ID_PRODUTOS,
        ID_PRODUTOSCONFIGPRECOS = produtosFornecedores.ID_PRODUTOSCONFIGPRECOS,
        NM_PRECO_REPOSICAO = (decimal)produtosFornecedores.NM_PRECO_REPOSICAO,
        ID_MOEDAS_REPOSICAO = (int)produtosFornecedores.ID_MOEDAS_REPOSICAO,
        ID_IMPOSTOSCONFIG = (int)produtosFornecedores.ID_IMPOSTOSCONFIG,
        ID_TABELANCMS = (int)produtosFornecedores.ID_TABELANCMS,
    };

var prodForn2_2 =
    from pf in prodForn2_1.ToArray()
    group ...

Now you just need to complete the prodForn2_2 with either of option (1) or (2) from above. Note that the ToArray call will force the prodForn2_1 query to execute and bring the records into memory as an array - grouping and sub-querying is then lightningly fast. You just need to watch out on memory use rather than query execution time.

I hope this helps.


I resolved using by this way:

var prodForn = from produtosFornecedores in ERPDAOManager.GetTable<ProdutosFornecedores>()
                                                   //Inner Join com Fornecedores
                                                   join fornecedores in ERPDAOManager.GetTable<Fornecedores>()
                                                        on produtosFornecedores.ID_FORNECEDORES equals fornecedores.ID
                                                   //Inner Join com Municipios
                                                   join municipios in ERPDAOManager.GetTable<Municipios>()
                                                       on fornecedores.ID_MUNICIPIOS equals municipios.ID
                                                   //Inner Join com UnidadesFederacao
                                                   join unidadesFederacao in ERPDAOManager.GetTable<UnidadesFederacao>()
                                                       on municipios.ID_UNIDADESFEDERACAO equals unidadesFederacao.ID
                                                   //Filtros
                                                   where produtosFornecedores.ID_PRODUTOS == Convert.ToInt32(objEsquemasCalculoRegras.CD_OBJETO1) &&
                                                         produtosFornecedores.ID_PRODUTOSCONFIGPRECOS == Convert.ToInt32(objEsquemasCalculoRegras.CD_OBJETO2) &&
                                                         produtosFornecedores.FG_STATUS == true
                                                   group produtosFornecedores by new
                                                   {
                                                       ID_IMPOSTOSDESTINOS = fornecedores.ID_IMPOSTOSDESTINOS,
                                                       ID_FORNECEDORES = fornecedores.ID,
                                                       CD_UF_BASE = unidadesFederacao.CD_UNIDADEFEDERACAO,
                                                       produtosFornecedores.ID_PRODUTOS,
                                                       produtosFornecedores.ID_PRODUTOSCONFIGPRECOS
                                                   } into grpProdutosFornecedores
                                                   select new
                                                   {
                                                       grpProdutosFornecedores.Key.ID_IMPOSTOSDESTINOS,
                                                       grpProdutosFornecedores.Key.ID_FORNECEDORES,
                                                       grpProdutosFornecedores.Key.CD_UF_BASE,
                                                       NM_PRECO_REPOSICAO = (decimal)grpProdutosFornecedores.Max(item => item.NM_PRECO_REPOSICAO),
                                                       ID_MOEDAS_REPOSICAO = (int)grpProdutosFornecedores.Max(item => item.ID_MOEDAS_REPOSICAO),
                                                       ID_IMPOSTOSCONFIG = (int)grpProdutosFornecedores.Max(item => item.ID_IMPOSTOSCONFIG),
                                                       ID_TABELANCMS = (int)grpProdutosFornecedores.Max(item => item.ID_TABELANCMS)
                                                   };

                                    if (prodForn.Count() > 0)
                                    {
                                        NM_VALOR1 = prodForn.First().NM_PRECO_REPOSICAO;
                                        NM_VALOR2 = prodForn.First().ID_MOEDAS_REPOSICAO;
                                        ID_IMPOSTOSDESTINOS = prodForn.First().ID_IMPOSTOSDESTINOS;
                                        ID_IMPOSTOSCONFIG = prodForn.First().ID_IMPOSTOSCONFIG;
                                        ID_TABELANCMS = prodForn.First().ID_TABELANCMS;
                                        ID_FORNECEDORES = prodForn.First().ID_FORNECEDORES;
                                        CD_UF_BASE = prodForn.First().CD_UF_BASE;
                                    }
0

精彩评论

暂无评论...
验证码 换一张
取 消