2011-08-03 33 views
0

使用Linq to Sql如何将下表(entidadeProdutosFornecedores)分组并从N个表中返回字段?Linq - 由多个表组成的多个表返回

原始查询在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 

查询转换为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 produtosFornecedores 
                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 
                }; 

回答

3

你与你的查询获得的问题是,你想后访问“从”变量“分组“,你不能这样做。为了得到这些变量,它们必须是(1)保持在分组之外或(2)成为分组本身的一部分。

(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), 
    }; 

给每个一去,看看哪些适合您的需要更好。

您也可能发现性能是分组和多个最大查询的问题,所以在分组结果之前将记录带入内存可能值得。

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 ... 

现在你只需要使用任一选项来完成prodForn2_2(1)或(2)从上面。请注意,ToArray调用将强制prodForn2_1查询执行并将记录作为数组存储到内存中 - 分组和子查询的速度非常快。你只需要注意内存使用而不是查询执行时间。

我希望这会有所帮助。

+0

嗨家伙,谢谢。我已经将所有字段分组,并且我按照您的选择(2)进行了分类。 – Gandarez

0

我决定使用这种方式:

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; 
            }