简体   繁体   中英

Convert this SQL query to LINQ?

Using a SQL query within Microsoft SQL Server, I am able to get my desired results. Now I'm trying to utilize this query in my project via LINQ.

My SQL query is

SELECT distinct DeviceId, max (Head), max(Shoulder), max(Chest)
FROM EventUserOverPressure eop
 JOIN UserEventInfo uei on uei.UserEventInfo_Id = eop.UserEventInfo_Id
JOIN BlastRecord br ON br.BlastRecord_Id = uei.BlastRecord_Id
JOIN WeaponsFiringLog wfl ON wfl.BlastRecord_Id = br.BlastRecord_Id
JOIN WeaponsFired wf ON wf.Blast_WFL_Id = wfl.Blast_WFL_Id
  WHERE br.BlastRecord_Id = 1599
  group BY DeviceId

Thus far, my LINQ query is

var myOverPressures = (from eop in db.EventUserOverPressures 
join uei in ueiList on eop.UserEventInfo_Id equals uei.UserEventInfo_Id
join br in blastRecords on uei.BlastRecord_Id equals br
join wfl in weaponFiringLogss on uei.BlastRecord_Id equals wfl.BlastRecord_Id
join wf in weaponsFired on wfl.Blast_WFL_Id equals wf.Blast_WFL_Id
where (eop.Chest > 0 || eop.Head > 0 || eop.Shoulder > 0)
select new { eop.DeviceDataId, eop.Head, eop.Shoulder, eop.Chest }).Distinct().ToList();

I know the BlastRecord_Id is set to 1599 and it's a variable in LINQ. That's intentional. I was trying to figure out my query in SQL, so I focused on specific record. In LINQ it needs to work for all BlastRecord_Id's. Using LINQ, I'm able to group by DeviceDataId on the next, outside of the initial query.

My goal is to group by DeviceDataId as part of this query, and get the max values for Head Shoulder and Chest - like I did in the SQL query. If it matters, my end goal is sort my results. I know my SQL query results give me what I need in order to sort how I want. I've spent an embarrassing amount of time trying to figure this out. Any help is greatly appreciated.

Try:

var myOverPressures = (
    from eop in db.EventUserOverPressures 
    join uei in ueiList on eop.UserEventInfo_Id equals uei.UserEventInfo_Id
    join br in blastRecords on uei.BlastRecord_Id equals br.BlastRecord_Id
    join wfl in weaponFiringLogss on uei.BlastRecord_Id equals wfl.BlastRecord_Id
    join wf in weaponsFired on wfl.Blast_WFL_Id equals wf.Blast_WFL_Id
    where (eop.Chest > 0 || eop.Head > 0 || eop.Shoulder > 0)
    select new { eop.DeviceDataId, eop.Head, eop.Shoulder, eop.Chest }
)
.GroupBy(r => r.DeviceDataId)
.Select(g => new {
    DeviceDataId = g.Key,
    maxHead = g.Max(r => r.Head),
    maxShoulder = g.Max(r => r.Shoulder),
    maxChest = g.Max(r => r.Chest)
})
.ToList();

The .GroupBy() maps the data to a collection of groups, each of which has a key and a collection of group member objects. The .Select() then extracts the key and calculates the max of the Head/Shoulder/Chest values within each group.

I removed the .Distinct() , as I believe it is unnecesary due to the fact that each group key ( DeviceDataId ) should already be distinct.

As a side note: I noticed that the join structure of your query has what appears to be two independent one-to-many join relationships:

BlastRecord
+--> UserEventInfo --> EventUserOverPressure
+--> WeaponsFiringLog --> WeaponsFired

This may lead to the results being the cartesian product of the two join paths, yielding duplicate data. This could be a problem if you were counting of summing the effects, but if max() is the only aggregation used, I do not believe the results are affected.

I believe the grouping and aggregation may also be done in the LINQ query syntax. Something like:

var myOverPressures = (
    ...
    group eop by eop.DeviceDataId into g
    select new {
        DeviceDataId = g.Key,
        maxHead = g.Max(r => r.Head),
        maxShoulder = g.Max(r => r.Shoulder),
        maxChest = g.Max(r => r.Chest)
    }
)
.ToList();

(I am not 100% sure I have this right. If someone spots an error and comments, I will correct the above.)

Try this one

var query = (from eop in db.EventUserOverPressure
            join uei in db.UserEventInfo on eop.UserEventInfo_Id equals uei.UserEventInfo_Id
            join br in db.BlastRecord on uei.BlastRecord_Id equals br.BlastRecord_Id
            join wfl in db.WeaponsFiringLog on br.BlastRecord_Id equals wfl.BlastRecord_Id
            join wf in db.WeaponsFired on wfl.Blast_WFL_Id equals wf.Blast_WFL_Id
            where br.BlastRecord_Id == 1599
            group eop by eop.DeviceId into g
            select new
            {
                DeviceId = g.Key,
                Head = g.Max(x => x.Head),
                Shoulder = g.Max(x => x.Shoulder),
                Chest = g.Max(x => x.Chest)
            });

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