简体   繁体   中英

LINQ query with group by and multiple counts

I'm trying to write a LINQ query using linq-to-entities in EF 6 to retrieve a list of water basins and their associated counts. The issue is that he child tables are in opposing directions.

I wish to do this without using a sub-select within the select clause for performance reasons. In SQL I would normally created Derived Views but don't know how to accomplish this via Linq.

A Basin has multiple Stations (Wells) associated to it as children. As parents it can be utilized by multiple Organizations who manage the Basins. I need a count of Stations and a count of Organizations per Basin.

I've tried group by however it appears to only support aggregating in one direction.

First the base query

(from b in EwmBasins
join s in EwmStations on b.BasinId equals s.BasinId into b_s_into
from b_s_from in b_s_into.DefaultIfEmpty()
join bp in EwmBasinPortions on b.BasinId equals bp.BasinId into bp_b_into
from bp_b_from in bp_b_into.DefaultIfEmpty()
join mnb in MonitoringNotificationBasins on bp_b_from.BasinPortionId equals mnb.BasinPortionId into mnb_bp_into
from mnb_bp_from in mnb_bp_into.DefaultIfEmpty()
where b.EwmB118VersionTypeId == EwmB118VersionTypes.Max(m => m.b118VersionTypeId)
group s_from.StationId by b into g
 select new 
 {
  BasinId = g.Key, 
  WellCount = g.ToList().Count(),
  //OrganizationCount = mnb_bp_from.MonitoringNotificatonId.Count() ??? how to do this
 }
)

I expect to see BasinId, # wells and # organizations such as:

  1 | 7 | 2
  2 | 2 | 0
  ...

EDIT

(from basin in EwmBasins
 where basin.EwmB118VersionTypeId == EwmB118VersionTypes.Max(m => m.b118VersionTypeId)
 select new
 {
    basin,
    WellCount = basin.Stations.Count()
 }
).OrderBy(o => o.basin.BasinCode)

It appears to work with @NetMage's suggestion using EF6 navigigational properties. It does generate a stack of sql statments, however the execution time is no slower than running the query posted in my question so I will go with it.

(from b in dbContext.EwmBasins
                                 where b.EwmB118VersionTypeId == dbContext.EwmB118VersionTypes.Max(m => m.b118VersionTypeId)
                                 select new
                                 {
                                     Basin = b,
                                     WellCount = b.Stations.Count(),
                                     OrganizationCount = b.BasinPortions.Count(a => a.MonitoringNotificationBasins.Any(c => c.MonitoringNotification != null))
                                 }
                                ).OrderBy(o => o.Basin.BasinCode)

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