简体   繁体   中英

Issues in converting SQL to LINQ

I have a sql query like below (table and column names are arbitrary for the sake of question):

select t3.MRIID as 'Ids'
from table1 t1  
    join table2 t2 with (nolock) on t1.ID = t2.SPID
    join table3 t3 with (nolock) on t2.ID = t3.SPMRID
    join table4 t4 on t4.MRID = t3.MRID
where 
    t3.MRISID = 18
    and t1.ID = 315
group by t3.MRIID
having SUM(CAST(t4.IRGPC AS INT)) > 0  

I am trying to convert this to an equivalent LINQ query and this is what I have so far. This does not give me the intended result when I run it in LINQPad and was wondering if anyone has explanation to where I am going wrong? I know my group/having clauses are the issues here but not sure how to solve it.

from t1 in table1
    join t2 in table2 on t1.ID equals t2.SPID
    join t3 in table3 on t2.ID equals t3.SPMRID
    join t4 in table4 on t3.MRID equals t4.ID
where t3.MRISID == 18 && t1.ID == 315
group new { t1, t2, t3, t4 } by t3.MRID into groupedResult
let count = groupedResult.Count()
where count > 0
select new { Something = groupedResult.Key}

The SQL query gives me 2 'Ids' in result which is expected as compared to Linq query giving me 3 out of which 1 'Id' does not match the having clause

Help greatly appreciated!

[UPDATE] I just noticed my having clause in sql query is not what is there in Linq equivalent and am trying to understand how to accomplish that?

Based on Mrinal's solution (and chat comments), My LINQ now stands at

from t1 in table1
    join t2 in table2 on t1.ID equals t2.SPID
    join t3 in table3 on t2.ID equals t3.SPMRID
    join t4 in table4 on t3.MRID equals t4.ID
where t3.MRISID == 18 && t1.ID == 315
group Convert.ToInt32(cd.IRGPC) by mriw.MRIID into groupedResult
where groupedResult.Sum() > 0
select new { groupedResult.Key}

However, this is still not matching the results of what the original SQL statement gives. I Ran this linq query through LinqPad to see the generated SQL and it looks like below.

-- Region Parameters
DECLARE @p0 Int = 18
DECLARE @p1 Int = 315
DECLARE @p2 Int = 0
-- EndRegion
SELECT [t5].[MRIID] AS [Key]
FROM (
    SELECT SUM([t4].[value]) AS [value], [t4].[MRIID]
    FROM (
        SELECT CONVERT(Int,[t3].[IRGPC]) AS [value], [t2].[MRISID], [t0].[ID], [t2].[MRIID]
        FROM [table1] AS [t0]
        INNER JOIN [table2] AS [t1] ON [t0].[ID] = [t1].[SPID]
        INNER JOIN [table3] AS [t2] ON [t1].[ID] = [t2].[SPMRID]
        INNER JOIN [table4] AS [t3] ON [t2].[MRIID] = [t3].[ID]
        ) AS [t4]
    WHERE ([t4].[MRISID] = @p0) AND ([t4].[ID] = @p1)
    GROUP BY [t4].[MRIID]
    ) AS [t5]
WHERE [t5].[value] > @p2

If this extra bit of detail helps, the IRGPC column is a bit type in SQL and bool type in C# code.

Any suggestions?

Try modifying the Linq query as follows:

from t1 in table1
join t2 in table2 on t1.ID equals t2.SPID
join t3 in table3 on t2.ID equals t3.SPMRID
join t4 in table4 on t3.MRID equals t4.ID
where t3.MRISID == 18 && t1.ID == 315
group new { t1, t2, t3, t4 } by t3.MRID into groupedResult
where groupedResult.Sum(y => (int)y.t4.IRGPC) > 0
select new { Something = groupedResult.Key }

Modification:

Changed the groupedResult.Count() > 0 to groupedResult.Sum(y => (int)y.t4.IRGPC) > 0 , since in the Sql query you have having SUM(CAST(t4.IRGPC AS INT)) > 0 , which needs to replicated in the Linq Query

EDIT 1:

As mentioned by OP, t4.IRGPC is a boolean type and use case is to get one grouping, which has at least one value true, try the following option:

group t4.IRGPC by t3.MRID into groupedResult
where groupedResult.Any(x => x) 

Instead of

let count = groupedResult.Count()
where count > 0

use where clause

where groupedResult.Sum(x => x.t4.IRGPC) > 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM