2015-10-01 3 views
0

У меня есть следующий SQL:Преобразовать этот SQL-запрос к Expression Linq лямбды

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/лямбды

+0

Мне любопытно, что у вас есть рабочий запрос, почему бы просто не запросить базу данных с этим, а не использовать LINQ? – user2366842

+0

Я смущен, потому что ваш исходный запрос выглядит неправильно. Разве JOIN не должен находиться на 'Queue.MonitorID = Monitor.MonitorID'? –

+0

Исправлен исходный запрос typo thanks! – somedev

ответ

1

Если вы используете 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); 
+1

Забыл новый анонимный класс 'new {monitor = m, queue = ...}' – juharr

+1

@juharr Спасибо, обновлено. –

+0

@RobertMcKee Интересно, это выглядит многообещающе, но у меня есть некоторые вопросы, конечно ... Это возвращает анонимный объект с монитором и очередью, в моем случае мне действительно нужен только монитор, так что бы вы сделали еще один выбор после того, просто вернуть монитор? Я предполагаю, что вы написали это так, потому что я сделал select * в примере. Спасибо за это, это было очень полезно. – somedev

1

Я не думаю, что ваш присоединиться к совершенно правильно, потому что у вас есть очереди слева присоединился к мониторам, очередь должна существовать, но монитор может нет. он также будет возвращать только одну очередь, потому что вы принимаете только первую очередь в подзапросе. Я думаю, что вы хотите настроить оператор 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); 
+0

Ваш подзапрос возвращает идентификатор максимальной очереди для каждого идентификатора монитора. Это не скалярное значение, поэтому вы не можете сравнить это с равными. – juharr

+0

Вы абсолютно правы, извините, не могли бы вы пересмотреть это еще раз для меня? – somedev

+0

@juharr спасибо, что поймал это. я исправил SQL –

1

Вы можете просто сделать запрос для всех мониторов, что не есть какие-либо очереди, созданные после порога.

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

Я не думаю, что есть веская причина использовать явное соединение здесь. На самом деле редко бывает с идиоматическими запросами EF.

Смежные вопросы