2014-12-17 6 views
2

Это рабочий SQL Мне нужно преобразованный в Linq:Преобразование SQL заявление Linq Заявление (3 таблица слева присоединяется + где)

select * from dbo.Pod p 
left join dbo.PodEvent pe on p.PodId = pe.Pod_PodId 
left join dbo.Event e on pe.Event_EventId = e.EventId 
where e.StartDateTime >= '2014-12-24 09:00:00.000' 
    and e.EndDateTime <= '2014-12-24 14:30:00.000' 

Я пытался предложения от различных сообщений весь день, и это лучший Я мог бы сделать, и вопрос в том, что его внутреннее соединение, где мне нужно, чтобы это было левое соединение, так что я могу получить все стручки для данного временного интервала:

List<Pod> pods = 
    (from p in db.Pods 
    join pe in db.PodEvents on p.PodId equals pe.Pod.PodId 
    join e in db.Events on pe.Event.EventId equals e.EventId 
    where 
    e.StartDateTime == userInfo.StartDateTime 
     && 
    e.EndDateTime <= userInfo.EndDateTime 
    select p).ToList(); 

Благодарности

+0

Попробуйте исследовать «GroupJoin». – Reddog

+0

Спасибо за предложение, я попробовал несколько примеров, но потом у меня проблемы с преобразованием моих результатов в список ... знаете ли вы о каком-либо материале? – OverMars

+1

Возможно, эта ссылка была бы полезной для вас: http://msdn.microsoft.com/en-us/vstudio/ee908647.aspx#leftouterjoin – Vokinneberg

ответ

3

Учитывая, что WHERE фильтр в вашем SQL будет эффективно отображать избыточное соединение Left Outer Join, поскольку любые неудачные JOINS будут filtered out by the WHERE clause, вы можете использовать этот факт, чтобы вручную спроектировать INNER JOIN через таблицу соединений без навигации (и производительность, вероятно, будет ужасной) :

var pods = db.Events.Where(e => e.StartDateTime >= userInfo.StartDateTime 
           && e.EndDateTime < userInfo.EndDateTime) 
        .Join(db.PodEvents, 
          e => e.EventID, 
          pe => pe.EventId, 
          new (e, pe) => { 
           Event = e, 
           PodEvent = pe, 
           Pod = db.Pods.Single(p => p.PodId == pe.PodID) 
          }) 
         .SelectMany(x => x.Pod); 

Однако, учитывая, что у вас есть навигация по pe.Event.EventId, почему бы не исправить навигации на всех трех таблиц, что позволит намного проще:

var pods = db.Events.Where(e => e.StartDateTime >= userInfo.StartDateTime 
           && e.EndDateTime < userInfo.EndDateTime) 
        .SelectMany(e => e.PodEvents.Select(pe => pe.Pod)); 

Кроме того, если PodEvent просто Junction Таблица (EventId, PodId) - путем моделирования этого как Многие: многие в EF вы можете полностью исключить объект соединения PodEvent, и Event и Pod станут непосредственно судоходными.

+0

Большое вам спасибо за такой подробный ответ! У меня есть возможность конвертировать мою таблицу соединений во многие :: многие отношения, и я это сделаю. Вы упомянули проблему с навигацией, какую-нибудь идею, как я могу решить ее? или удалит таблицу соединений, исправьте проблему? – OverMars

+1

В Sql у вас должна быть таблица соединений, но в EF, если вам нужны только клавиши N: N в таблице, вы можете перемещаться по ней, как если бы она была невидимой - см. Http://stackoverflow.com/a/ 5418534/314291 и http://stackoverflow.com/questions/21954520/creating-many-to-many-relationships-using-fluent-api-in-entity-framework – StuartLC

+0

Прошу простить мое невежество. Вы имеете в виду, что если я буду делать все через EF (что я есть), то мне не нужна моя таблица соединений? или Мне нужен мой соединительный стол на стороне sql, но у меня может быть EF, думаю, что его не существует? – OverMars

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