遇到Sql To Linq的问题

时间:2016-03-29 13:50:38

标签: c# sql linq

我有一个SQL查询设置:

select
  sm.coddeposito as coddeposito,
  rd.codart as codart,
  ast.codsottotipo as codsottotipo,
  ast.descrizionesottotipo as descrizionesottotipo,
  sum(sm.GIACENZA * sm.QTA1UM) as giacenza1,
  sum(sm.GIACENZA2UM * sm.QTA2UM) as giacenza2,
  sum(sm.ordinato * sm.QTA1UM) as ordinato1,
  sum(sm.ordinato2UM * sm.QTA2UM) as ordinato2,
  sum(sm.impegnato * sm.QTA1UM) as impegnato1,
  sum(sm.impegnato2UM * sm.QTA2UM) as impegnato2
from Programmi.dbo.SAN_STORICOMAG as sm
join programmi.dbo.san_righedocumenti 
  as rd on sm.IDTESTA = rd.idtesta and sm.rigadoc = rd.idriga
join programmi.dbo.SAN_EXTRARIGHEDOC 
  as erd on rd.idtesta = erd.idtesta and rd.idriga = erd.idriga 
join programmi.dbo.tk_tab_anasottotipi 
  as ast on erd.tk_codsottotipo = ast.CODSOTTOTIPO
where sm.codart like '%RTM%' 
  and erd.Tk_CodSottotipo <> '' 
  and erd.Tk_CodSottotipo is not null
group by 
  sm.coddeposito, 
  rd.codart,  
  ast.codsottotipo, 
  ast.descrizionesottotipo
order by 
  sm.coddeposito, 
  rd.codart,  
  ast.codsottotipo, 
  ast.descrizionesottotipo

我找到了一种方法来执行group by语句,但它不像我的SQL那样工作。 那是我的Linq查询:

from sm in db.SAN_STORICOMAG
from rd in 
  db.SAN_RIGHEDOCUMENTI.Where(x => x.IDTESTA.Equals(sm.IDTESTA ?? 0) 
  && x.IDRIGA.Equals(sm.RIGADOC ?? 0))
from erd in 
  db.SAN_EXTRARIGHEDOC.Where(x => x.IDTESTA.Equals(rd.IDTESTA) 
  && x.IDRIGA.Equals(rd.IDRIGA))
from ast in 
  db.TK_TAB_ANASOTTOTIPI.Where(x => x.CODSOTTOTIPO.Equals(erd.Tk_CodSottotipo))
where sm.CODART.Contains("RTM")
  && erd.Tk_CodSottotipo != string.Empty
  && erd.Tk_CodSottotipo != null
orderby 
  sm.CODDEPOSITO, 
  rd.CODART, 
  ast.CODSOTTOTIPO, 
  ast.DESCRIZIONESOTTOTIPO
group new Result
{
  CODDEPOSITO = sm.CODDEPOSITO,
  CODART = rd.CODART,
  DESCRIZIONEART = rd.DESCRIZIONEART,
  CODSOTTOTIPO = ast.CODSOTTOTIPO,
  DESCRIZIONESOTTOTIPO = ast.DESCRIZIONESOTTOTIPO,
  GIACENZA1 = (sm.GIACENZA * sm.QTA1UM) ?? 0,
  GIACENZA2 = (sm.GIACENZA2UM * sm.QTA2UM) ?? 0
}
by new
{
  sm.CODDEPOSITO,
  rd.CODART,
  ast.CODSOTTOTIPO,
  ast.DESCRIZIONESOTTOTIPO
}
into x
from xx in x
select xx

另一个问题是,使用此LINQ查询,我无法在声明组之后访问其中的成员。

2 个答案:

答案 0 :(得分:1)

我将提出一个不同的解决方案(所以不直接解决Linq语句)。对于更复杂的查询(并且这一点不是太复杂),通常最好创建一个SQL视图,然后基于该Sql View在c#中创建一个EF模型。这也将允许您更轻松地调整sql,而无需重新访问c#中的Linq查询以查看它在Sql中生成的内容。 sql中的最终结果(linq查询和生成的sql语句之间的转换)可能会因您使用的ORM而异,因为自定义sql视图始终是静态的(它保持您定义的方式)。

创建视图:

CREATE VIEW MyCustomView
AS
select
  sm.coddeposito as coddeposito,
  rd.codart as codart,
  ast.codsottotipo as codsottotipo,
  ast.descrizionesottotipo as descrizionesottotipo,
  sum(sm.GIACENZA * sm.QTA1UM) as giacenza1,
  sum(sm.GIACENZA2UM * sm.QTA2UM) as giacenza2,
  sum(sm.ordinato * sm.QTA1UM) as ordinato1,
  sum(sm.ordinato2UM * sm.QTA2UM) as ordinato2,
  sum(sm.impegnato * sm.QTA1UM) as impegnato1,
  sum(sm.impegnato2UM * sm.QTA2UM) as impegnato2
from Programmi.dbo.SAN_STORICOMAG as sm
join programmi.dbo.san_righedocumenti 
  as rd on sm.IDTESTA = rd.idtesta and sm.rigadoc = rd.idriga
join programmi.dbo.SAN_EXTRARIGHEDOC 
  as erd on rd.idtesta = erd.idtesta and rd.idriga = erd.idriga 
join programmi.dbo.tk_tab_anasottotipi 
  as ast on erd.tk_codsottotipo = ast.CODSOTTOTIPO
where sm.codart like '%RTM%' 
  and erd.Tk_CodSottotipo <> '' 
  and erd.Tk_CodSottotipo is not null
group by 
  sm.coddeposito, 
  rd.codart,  
  ast.codsottotipo, 
  ast.descrizionesottotipo
order by 
  sm.coddeposito, 
  rd.codart,  
  ast.codsottotipo, 
  ast.descrizionesottotipo

你的c#Model (我猜你的类型在这里)

public class MyModel {
    public object coddeposito { get; set; }
    public object codart { get; set; }
    public object codsottotipo { get; set; }
    public object descrizionesottotipo { get; set; }
    public int giacenza1 { get; set; }
    public int giacenza2 { get; set; }
    public int ordinato1 { get; set; }
    public int ordinato2 { get; set; }
    public int impegnato1 { get; set; }
    public int impegnato2 { get; set; }
}

您没有提及这是Linq还是EF或其他ORM,但您的下一步是映射此模型的方式与您使用的ORM中的其他模型相同。

如果你知道这些过滤器是动态的,你也可以删除WHERE子句中的一些过滤器。然后,您仍然可以根据需要在Linq代码中应用它们。

<强>声明 我没有检查你的查询的准确性或效率,所以如果有错误或更好的方法来产生连接,我没有找到它们。

答案 1 :(得分:0)

这样的事情应该这样做:

from sm in Programmi.dbo.SAN_STORICOMAG
join rd in programmi.dbo.san_righedocumenti 
    on new { condition1 = sm.IDTESTA, condition2 = sm.rigadoc } 
    equals new { condition1 = rd.idtesta, condition2 = rd.idriga }
join erd in programmi.dbo.SAN_EXTRARIGHEDOC 
    on new { condition1 = rd.idtesta, condition2 = rd.idriga } 
    equals new { condition1 = erd.idtesta, condition2 = erd.idriga }
join ast in programmi.dbo.tk_tab_anasottotipi 
    on erd.tk_codsottotipo 
    equals ast.CODSOTTOTIPO
where sm.codart.Contains("RTM")
and erd.Tk_CodSottotipo <> '' 
and erd.Tk_CodSottotipo != null
group new { 
    Giacenza = sm.GIACENZA, 
    Qta1um = sm.QTA1UM, 
    Giacenza2um = sm.GIACENZA2UM, 
    Qta2um = sm.QTA2UM,
    Ordinato = sm.ordinato,
    Ordinato2UM = sm.ordinato2UM,
    Impegnato = sm.impegnato,
    Impegnato2UM = sm.impegnato2UM
} 
by new { 
    Coddeposito = sm.coddeposito, 
    Codart = rd.codart, 
    Codsottotipo = ast.codsottotipo, 
    Descrizionesottotipo = ast.descrizionesottotipo 
} into g
order by g.Key.Coddeposito, g.Key.Codart, g.Key.Codsottotipo, g.Key.Descrizionesottotipo
select new 
{ 
    coddeposito = g.Key.Coddeposito, 
    codart = g.Key.Codart, 
    codsottotipo = g.Key.Codsottotipo, 
    descrizionesottotipo  = g.Key.Descrizionesottotipo, 
    giacenza1 = g.Sum(p => p.Giacenza * p.Qta1um),
    giacenza2 = g.Sum(p => p.Giacenza2um * p.Qta2um),
    ordinato1 = g.Sum(p => p.Ordinato * p.Qta1um),
    ordinato2UM = g.Sum(p => p.Ordinato2UM * p.Qta2um),
    impegnato1 = g.Sum(p => p.Impegnato * p.Qta1um),
    impegnato2 = g.Sum(p => p.Impegnato2UM * p.Qta2um)
}