繁体   English   中英

将此SQL查询转换为Linq Lambda表达式

[英]Convert this SQL Query to a Linq Lambda Expression

我有以下SQL:

select Monitor.* from Monitor 
left join Queue on Queue.MonitorID = Monitor.MonitorID
and Queue.QueueID = (select top 1 Queue.QueueID from Queue where Queue.MonitorID = Monitor.MonitorID order by Queue.Created)
where Queue.Created is null or Queue.Created < 'DateTimeValue'

如果您可以想到获取该信息也更好的更好方法,则此查询将选择队列已过期或缺失的所有“监视器”。

该查询的结果是需要运行的过期项目。 我正在使用EF6。

我试图将其从SQL转换为Linq Lambdas,我尝试了Linqer,但它似乎没有输出Lambda示例,或者我找不到实现它的设置。

因此,有人可以帮助指导我转换此查询并提供改进吗? 我知道子查询是性能杀手...

一旦我看完它,便觉得我将能够学习语法。

我正在linq / lambdas中寻找这种连接语法的示例

我不认为您的联接是正确的,因为您有一些队列已加入监视器,队列必须存在,但监视器可能不存在。 它也将只返回一个队列,因为您只在子查询中使用第一个队列。 我认为您想将SQL语句调整为

 select * from Monitor 
 left join Queue on Monitor.MonitorID = Queue.QueueID
 and Queue.QueueID in (select max(Queue.QueueID) from Queue group by Queue.MonitorID)
 /*this assumes queues are stored in sequential order*/
 where Queue.Created is null or Queue.Created < 'DateTimeValue'

然后您可以编写以下linq语句

 var monitors = _context.Set<Monitor>();
 var queues = _context.Set<Queue>();

 var queueIds = queues
      .GroupBy(q => q.MonitorID)
      .Select(q => q.Max(x => x.QueueID));

 return monitors
      .GroupJoin(queues.Where(q => queueIds.Contains(q.QueueID)), 
                 m => m.MonitorID, 
                 q => q.QueueID, 
                 (m, q) => new { monitor = m, queue = q.FirstOrDefault() })
      .Where(x => x.queue == null || x.queue.Created < date);

如果您将Entity Framework与导航属性一起使用,它将是:

var result=db.Monitors
  .Select(m=> new {
    monitor=m,
    queue=m.Queues.OrderByDescending(q=>q.Created).FirstOrDefault()
  })
  .Where(m=>m.queue.Created==null || m.queue.Created < DateTimeValue);

您可以查询所有在阈值之后创建任何队列的监视器。

var result = db.Monitors
  .Where(m => !m.Queues.Any(q => q.Created >= DateTimeValue));

我认为没有必要在此处使用显式联接。 实际上,很少有惯用的EF查询。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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