在我的API项目中,使用EntityFramework,我必须翻译以下SQL语句
select p.cod_paquete, p.nombre, a.descripcion, a.proceso, a.color, a.descripcion, (select count(*) from paqueteAcabado where paquete=a.paquete and color=a.color), coalesce(pc.titulo,''), case when pc.opcional=1 then 1 else 0 end as opcional, pa.optativo, a.opcional
from paqueteAPP pa
inner join paquete p on p.cod_paquete=pa.paquete
left join paqueteAcabado a on a.paquete=p.cod_paquete and a.opcional=1
left join coste c on c.cod_coste=a.acabado
left join paqueteColor pc on pc.paquete=p.cod_paquete and pc.color=a.color
where pa.agrupacionProductoProducto= '298'
order by coalesce(pa.orden,0), p.cod_paquete, a.color, a.descripcion
课程
public class SQLResultadoPaquetesAcabado
{
public short cod_paquete { get; set; }
public string nombre { get; set; }
public string descripcion { get; set; }
public short proceso { get; set; }
public string color { get; set; }
public int? paquetesColor { get; set; }
public string titulo { get; set; }
public bool? PaqueteColoropcional { get; set; }
public bool optativo { get; set; }
public bool? acabadoOpcional { get; set; }
}
在Linq中翻译的sql
int codigo = 298;
Paquetes = (from paqueteAPP pa in db.paqueteAPP
join paquete p in db.paquete on pa.paquete equals p.cod_paquete
join paqueteAcabado a in db.paqueteAcabado on p.cod_paquete equals a.paquete into pcacabado
from pacabado in pcacabado.DefaultIfEmpty()
join coste c in db.coste on pacabado.acabado equals c.cod_coste into pacabadocoste1
from pcosteacabado in pacabadocoste1.DefaultIfEmpty()
join paqueteColor pc in db.paqueteColor on p.cod_paquete equals pc.paquete into pcolor
from pacolor in pcolor.DefaultIfEmpty()
where pa.agrupacionProductoProducto == codigo && pacabado.opcional == true
select new SQLResultadoPaquetesAcabado
{
cod_paquete = p.cod_paquete,
nombre = p.nombre,
descripcion = pacabado.descripcion,
proceso = pacabado.proceso,
color = pacabado.color,
paquetesColor = (from paqueteAcabado pa in db.paqueteAcabado
where pa.paquete == pacabado.paquete && pa.color ==
pacabado.color
select pa).Count(),
titulo = pacolor.titulo,
PaqueteColoropcional = pacolor.opcional,
optativo = pa.optativo,
acabadoOpcional = pacabado.opcional
});
从Linq转换为SQL时获得的SQL
SELECT COUNT
[Project1].[agrupacionProductoProducto] AS [agrupacionProductoProducto],
[Project1].[cod_paquete] AS [cod_paquete],
[Project1].[nombre] AS [nombre],
[Project1].[descripcion] AS [descripcion],
[Project1].[proceso] AS [proceso],
[Project1].[color] AS [color],
[Project1].[C1] AS [C1],
[Project1].[titulo] AS [titulo],
[Project1].[opcional1] AS [opcional],
[Project1].[optativo] AS [optativo],
[Project1].[opcional] AS [opcional1]
FROM ( SELECT
[Filter1].[agrupacionProductoProducto] AS [agrupacionProductoProducto],
[Filter1].[optativo] AS [optativo],
[Filter1].[cod_paquete] AS [cod_paquete],
[Filter1].[nombre] AS [nombre],
[Filter1].[proceso] AS [proceso],
[Filter1].[descripcion] AS [descripcion],
[Filter1].[opcional] AS [opcional],
[Filter1].[color] AS [color],
[Extent4].[titulo] AS [titulo],
[Extent4].[opcional] AS [opcional1],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[paqueteAcabado] AS [Extent5]
WHERE ([Extent5].[paquete] = [Filter1].[paquete1]) AND (([Extent5].[color] = [Filter1].[color]) OR (([Extent5].[color] IS NULL) AND ([Filter1].[color] IS NULL)))) AS [C1]
FROM (SELECT [Extent1].[agrupacionProductoProducto] AS [agrupacionProductoProducto], [Extent1].[optativo] AS [optativo], [Extent2].[cod_paquete] AS [cod_paquete], [Extent2].[nombre] AS [nombre], [Extent3].[proceso] AS [proceso], [Extent3].[paquete] AS [paquete1], [Extent3].[descripcion] AS [descripcion], [Extent3].[opcional] AS [opcional], [Extent3].[color] AS [color]
FROM [dbo].[paqueteAPP] AS [Extent1]
INNER JOIN [dbo].[paquete] AS [Extent2] ON [Extent1].[paquete] = [Extent2].[cod_paquete]
INNER JOIN [dbo].[paqueteAcabado] AS [Extent3] ON [Extent2].[cod_paquete] = [Extent3].[paquete]
WHERE 1 = [Extent3].[opcional] ) AS [Filter1]
LEFT OUTER JOIN [dbo].[paqueteColor] AS [Extent4] ON [Filter1].[cod_paquete] = [Extent4].[paquete]
WHERE [Filter1].[agrupacionProductoProducto] = '298'
) AS [Project1]
我的问题是SQL由三个左联接组成
使用linq,我只能生成一个左连接,正如从linq生成sql的结果中所看到的那样
SQL
left join paqueteAcabado a on a.paquete=p.cod_paquete and a.opcional=1
left join coste c on c.cod_coste=a.acabado
left join paqueteColor pc on pc.paquete=p.cod_paquete and pc.color=a.color
Linq
INNER JOIN [dbo].[paquete] AS [Extent2] ON [Extent1].[paquete] = [Extent2].[cod_paquete]
INNER JOIN [dbo].[paqueteAcabado] AS [Extent3] ON [Extent2].[cod_paquete] = [Extent3].[paquete]
WHERE 1 = [Extent3].[opcional] ) AS [Filter1]
LEFT OUTER JOIN [dbo].[paqueteColor] AS [Extent4] ON [Filter1].[cod_paquete] = [Extent4].[paquete]
我的问题是,如何通过linq成功地重现SQL而又不使用非重复?因为有了独特的结果,我得到了想要的结果,但是却得到了120个重复的行,这是我不想要的
答案 0 :(得分:0)
我使用自己的代码,但是代码转换非常困难。但是,我尝试解释如何创建类似于sql查询的左外部联接。
请记住,这不是最终查询。您必须添加内部查询(我想可以),如果您获得的join关键字不匹配异常,则应添加相同的名称。
现在代码在这里,我尝试转换一些部分:
var joinTest = context.paqueteAPP.Join(context.paquete,
pa => pa.paquete,
p => p.cod_paquete,
(pa, p) =>
new {p.cod_paquete, p.nombre,p.cod_paquete})
.GroupJoin(context.paqueteAcabado,
a => new
{
a.paquete,
a.opcional
},
temp => new {paquete=temp.cod_paquete,opcional=1},
(temp, paqueteAcabado) => new {temp.cod_paquete, temp.nombre, paqueteAcabado})
.SelectMany(s => s.paqueteAcabado.DefaultIfEmpty(),
(s, paqueteAcabado) => new {s.cod_paquete, s.nombre,paqueteAcabado.descripcion, paqueteAcabado.proceso, paqueteAcabado.color, paqueteAcabado.descripcion,paqueteAcabado.acabado})
.GroupJoin(context.coste,
a => a.acabado, c => c.cod_coste,
(temp, coste) => new { temp.cod_paquete, temp.nombre,temp.descripcion, temp.proceso, temp.color, temp.descripcion, coste })
.SelectMany(s => s.coste.DefaultIfEmpty(),
(s, coste) => new { s.cod_paquete, s.nombre,s.descripcion, s.proceso, s.color, s.descripcion, coste.Name })
.ToList();
此查询创建1个内部联接和2个左联接。
如果需要更多帮助,请添加实体(所需)和一些数据。