2014-02-16 159 views
2

我正在使用Linq與實體框架5和使用查詢語法(我認爲,請糾正我的術語)。我有一張參與者表格,並且希望將他們的學習ID號碼與記錄的SMS消息相關聯,其中消息中的「to」或「from」號碼與參與者的電話號碼相匹配。此外,我希望從(或到)未知號碼發送的郵件也顯示在列表中,在這種情況下,學習ID號碼將爲空。使用where子句的實體框架+ Linq 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?

編輯:請參閱下面我自己的答案。

+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,對於左外部連接,如果我要加入術語更正會給我一個沒有發送或接收任何消息的參與者列表,是的?其他人發現這令人困惑? –

回答

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使它成爲一個左連接,並且在Db.participants.DefaultIfEmpty()中添加來自pp的'似乎不起作用。 –