【问题标题】:How can I merge two LINQ queries into one query?如何将两个 LINQ 查询合并为一个查询?
【发布时间】:2017-07-04 21:54:30
【问题描述】:

我有以下 SQL 查询:

select 
    [Event2].EventType AS 'Event type', 
    SUM (1)            AS 'Number of events', 
    AVG(DATEDIFF(Second, [Event1].CreationDate, [Event2].CreationDate)) AS 'Time'
from [Event] as [Event1]
join [Event] as [Event2] on [Event1].Id = [Event2].ParentId
group by [Event2].EventTypeId;

为此我找到了两个 LINQ 查询。

// This query brings the event types and the differences between the events.
var rows = from event1 in _eventRepository.AsQueryable()
           join event2 in _eventRepository.AsQueryable() on event1.Id equals event2.ParentId
           select new 
           {
               EventId = event2.EventId, 
               TimeInSeconds = DbFunctions.DiffSeconds(event1.CreationDate, event2.CreationDate) 
           };

// This query groups the rows before by Event type.
var groups = (from item in rows  
              group item by item.EventTypeId into g
              select new EventModel
              {
                  EventTypeId = g.Key,
                  NumberOfEvents = g.Sum(x => 1),
                  Time = (int) g.Average(x => x.TimeInSeconds)
              }).ToList();

我必须将这些查询合并为一个。 结果必须包含三个元素:第一个事件的创建日期和第二个事件的创建日期之间经过的时间:Event TypeThe number of eventsThe Average

【问题讨论】:

  • 为什么一定要合并成一个?
  • 因为 Event 表在某个时间可能包含很多行,并且带入内存的数据太多。
  • @PianoSong - 直到ToList(),数据才会被带回内存
  • 是什么让您认为第一个查询会将任何内容带入内存@PianoSong?我建议试一试hibernatingrhinos.com/products/efprof。您可能会惊讶地看到哪些行实际上导致 SQL 被执行。

标签: c# sql entity-framework linq


【解决方案1】:

您应该只将分组语句添加到第一个查询(而不是选择):

var result = (from event1 in _eventRepository
              join event2 in _eventRepository on event1.Id equals event2.ParentId

              group new {
                EventId =  event2.EventId,
                TimeInSeconds = DbFunctions.DiffSeconds(event1.CreationDate, event2.CreationDate)
              }
              by event2.EventTypeId into g

              select new EventModel {
                EventTypeId = g.Key,
                NumberOfEvents = g.Count(),
                Time = (int) g.Average(x => x.TimeInSeconds)
              }).ToList();

您也可以不指定分组中的字段,而只在选择语句中指定字段,但保留原样

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多