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;
}
精彩评论