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 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
};
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)
(2)
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.
Now you just need to complete the
prodForn2_2with either of option (1) or (2) from above. Note that theToArraycall will force theprodForn2_1query 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.