2016-03-29 4 views
-1

у меня есть SQL-запрос установить:Возникли проблемы с Sql К Linq

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 

Я нашел способ сделать группу заявлением, но он не работает, как мой 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, я не могу получить доступ к членам внутри нее, после того, как группы по декларации.

+0

Когда LINQ побежал у него есть количество членов? "в x из xx в x" звучит как плохой бит именования происходит там .. Что произойдет, если вы создадите свою структуру, вы создаете первый бит имен linq, а не только новый {}? поэтому новый {Coddepostio = sm.CODDEPOSTIO ..etc} – BugFinder

+0

Честно говоря, с комплексными запросами (и этот не слишком сложен каким-либо образом), как правило, намного проще создавать представление SQL, а затем создавать EF-модель в C# на основе этого Sql View. Это также позволит вам более легко подстроить sql, как вам удобно, без необходимости повторять запрос Linq в C#, чтобы узнать, что он производит в Sql. – Igor

+0

Вам не хватает «левого внешнего соединения»? См. Ниже: https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b – jdweng

ответ

1

Я собираюсь предложить другое решение (поэтому не обращаюсь непосредственно к заявлению Linq). С более сложными запросами (и это не слишком сложно каким-либо образом), как правило, лучше создать представление SQL, а затем создать EF-модель в C# на основе этого Sql View. Это также позволит вам более легко подстроить sql, как вам удобно, без необходимости повторять запрос Linq в C#, чтобы узнать, что он производит в 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# Модель (я предполагаю, что в ваших типов здесь):

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

Спасибо, igor! :) –

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) 
} 
Смежные вопросы