Linq -组由多个表与多个返回
本文关键字:返回 -组 Linq | 更新日期: 2023-09-27 18:04:38
使用Linq to Sql如何将以下表(entidadeproductofornecedores)分组并从N个表返回字段?
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
};
您的查询得到的问题是,您正试图访问"从"变量之后的"组",你不能这样做。为了获得这些变量,它们必须要么(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),
};
每个都试一试,看看哪个更适合你的需要。
您可能还会发现性能是分组和多个max查询的问题,因此在分组结果之前将记录放入内存可能是值得的。
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 ...
现在您只需要用上面的选项(1)或(2)中的任何一个完成prodForn2_2
。注意,ToArray
调用将强制执行prodForn2_1
查询,并将记录作为一个数组放入内存中——分组和子查询的速度很快。你只需要注意内存的使用而不是查询的执行时间。
我用这种方法解决了使用问题:
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;
}