[英]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.