2014-02-16 4 views
2

Я использую Linq с Entity Framework 5 и используя синтаксис запроса (я думаю, пожалуйста, исправьте мою терминологию). У меня есть таблица участников и хочу связать их идентификационный номер исследования с зарегистрированным SMS-сообщением, в котором номер сообщения «to» или «from» в сообщении соответствует номеру телефона участника. Кроме того, я хочу, чтобы сообщения, отправленные из (или) неизвестного номера, отображались в списке, и в этом случае номер идентификатора исследования был бы нулевым.Entity Framework + Linq LEFT JOIN с использованием предложения where?

Вот рабочий сырым запрос для LEFT JOIN (с использованием базы данных MySQL, если это имеет значение):

SELECT 
    messages._id, participants.study_id_number, messages.ts, 
    messages.from_phone, messages.to_phone, messages.body 
FROM messages LEFT JOIN 
    participants ON ( (participants.phone_number = messages.to_phone) 
        || (participants.phone_number = messages.from_phone)) 
ORDER BY messages.ts DESC; 

Вот что я работаю до сих пор в Linq, но это внутреннее соединение:

var loggedMessages = from pp in theDb.participants 
        let phone = pp.phone_number 
        from mm in theDb.messages 
        let fromPhone = mm.from_phone 
        let toPhone = mm.to_phone 
        where ((phone == fromPhone) || (phone == toPhone)) 

        orderby mm.ts descending 
        select new MessageLogEntry() 
        { 
         ParticipantId = pp.study_id_number, 
         TimeStamp = mm.ts, 
         FromPhone = fromPhone, 
         ToPhone = toPhone, 
         Body = mm.body 
        }; 

Я новичок в этом, поэтому я был бы доволен ссылкой на учебник по запросам Linq, но что мне нужно добавить, чтобы сделать его LEFT JOIN?

EDIT: см. Мой собственный ответ ниже.

+0

Существует действительно учебник от Microsoft: http://msdn.microsoft.com/en-us/library/bb397895.aspx –

+0

http://codingsense.wordpress.com/2009/03/08/left-join -right-join-using-linq/ – wdosanjos

+0

@Michael Dunlap, это для левого соединения OUTER, которое, если я получаю правильную терминологию соединения, даст мне список участников, которые не отправляли и не получали никаких сообщений, да? Кто-нибудь другой считает это запутанным? –

ответ

2

После некоторого быстрого и неглубоко исследования, а также несколько более SO ссылки, у меня есть следующие генерации желаемого результата. Комментарии очень приветствуются, самая большая вещь, которую я узнал из этого упражнения, - это то, насколько я должен учиться!

var loggedMessages = from mm in theDb.messages 
        from pp in theDb.participants 
        .Where(pp1 => ((mm.from_phone == pp1.phone_number) || (mm.to_phone == pp1.phone_number))) 
        .DefaultIfEmpty() 
        orderby mm.ts descending 
        select new MessageLogEntry() 
        { 
         ParticipantId = (int?)pp.study_id_number, 
         TimeStamp = mm.ts, 
         FromPhone = mm.from_phone, 
         ToPhone = mm.to_phone, 
         Body = mm.body 
        }; 

Я немного испуган, как она идет от синтаксиса запросов к синтаксису методы и обратно, но он составлен, LINQPad понравилась и показала правильный результат, и он проверяет вне. Я понятия не имею, насколько результативен он по сравнению с тем, насколько он мог бы быть, это для будущего урока.

И LinqPad это потрясающе!

4

Вам необходимо добавить DefaultIfEmpty(), чтобы сделать его левым.

Проверьте это:

var loggedMessages = from pp in theDb.participants 
        join mm in theDb.messages 
        on pp.phone_number equals mm.to_phone || 
        pp.phone_number equals mm.from_phone 
        into joinedmm 
        from pm in joinedmm.DefaultIfEmpty() 
        orderby mm.ts descending 
        select new MessageLogEntry() 
        { 
         ParticipantId = pp.study_id_number, 
         TimeStamp = pm.ts, 
         FromPhone = fromPhone, 
         ToPhone = toPhone, 
         Body = pm.body 
        }; 
+0

Спасибо, но я опережаю вас. :) В синтаксисе соединения нет «или». Это проблема №1. Проблема №2 делает его левым соединением, и добавление 'из pp в Db.participants.DefaultIfEmpty()', похоже, не работает. –