2010-05-27 92 views
1

我有兩個表:如何在第二個表中的兩個字段上進行表連接?

  • 消息 - 除其他事項外,有一個to_idfrom_id場。
  • 人 - 有相應的PERSON_ID

我試圖找出如何做到以下幾點單一LINQ查詢:

給我已發送所有消息,從人x(idself)。

我在這有幾個裂縫。

不太正確

MsgPeople = (from p in db.people 
      join m in db.messages on p.person_id equals m.from_id 
      where (m.from_id == idself || m.to_id == idself) 
      orderby p.name descending 
      select p).Distinct(); 

這幾乎工作,但我認爲它忽略了一個情況:

「誰從來沒有收到消息的人,只是送一個給我」

這是如何工作在我的腦海

所以我真的需要的是這樣的:

join m in db.messages on (p.people_id equals m.from_id or p.people_id equals m.to_id) 

獲取我,我以後

看來你不能這樣做的人的一個子集。我已經嘗試了一些其他選擇,如 做兩聯接:

MsgPeople = (from p in db.people 
      join m in db.messages on p.person_id equals m.from_id 
      join m2 in db.messages on p.person_id equals m2.to_id 
      where (m2.from_id == idself || m.to_id == idself) 
      orderby p.name descending 
      select p).Distinct(); 

,但是這給了我我需要的結果的一個子集,我想的東西 做的加入被解決的順序。

我對LINQ(甚至可能是數據庫理論)的理解是令人尷尬的膚淺,我期待着解決我的問題。

回答

2

人;其中發送從自我的消息對自身或收到的消息。

from p in People 
where p.SentMessages.Any(m => m.to_id == idself) 
    || p.ReceivedMessages.Any(m => m.from_id == idself) 
select p; 

如果人們沒有這些消息的屬性,create the associations


如果你想拉牙齒而不是......這裏是沒有關聯的查詢。

IQueryable<int> sentQuery = 
    from sent in Messages 
    where sent.to_id = idself 
    select sent.from_id; 

IQueryable<int> receivedQuery = 
    from received in Messages 
    where received.from_id = idself 
    select received.to_id 

IQueryble<People> result = 
    from p in people 
    where System.Linq.Queryable.Concat(receivedQuery, sentQuery) 
    .Any(id => id == p.personId) 
    select p; 
+0

我避免這種情況,因爲這可能會導致一些錯過,關聯只能在一個字段,所以說你選擇to_id,如果在idself的人沒有發送電子郵件它會被錯過,因爲這產生將SELECT [T 0]的SQL [PERSON_ID] FROM [人] AS [T 0] WHERE EXISTS( SELECT NULL AS [清空] FROM [消息] AS [T1] WHERE (([t1]。[to_id] = @ p0)OR([t1]。[from_id] = @ p1))AND([t1]。[to_id] = [t0]。[Person_id]) ) 我認爲 – Pharabus 2010-05-28 17:18:24

+0

我錯過了人與消息之間存在多重關係的事實。固定! – 2010-05-28 17:36:26

+0

是啊,從我使用關係:)從我工作+1也我發現LINQPad很好地命名協會! – Pharabus 2010-05-28 17:41:13

1

也許我錯過了一些東西,但它似乎你不需要一個連接,你說:「給我所有的信息已發送到和從人x(idself)。「所以,如果你只是想消息,你可以只從他的消息工作表中,作爲ID(idself)被稱爲

var MsgPeople from p in AllMessages 
        where p.from_id == idself || p.to_id == idself 
        select p; 

沒關係,試試這個,你真的需要對誰發送的郵件你的人ID列表,和那些從您收到的郵件列表,那麼你可以從人們存在於該列表

var MsgPeople = from p in db.people 
         where (from m in db.messages 
           where m.from_id == selfid 
           select m.to_id).Union(
         from m in db.messages 
         where m.to_id == selfid 
         select m.from_id).Contains(p.person_id) 
         select p; 

另一種方式任何人做這個選擇,一個我從逆向工程SQL得到了我們的DBA,當我向他提出問題

var MsgPeople = from p in Peoples 
    where p.Person_id != selfid && 
    (from m in Messages 
    where m.To_id == selfid select m.From_id).Union(
    from m in Messages 
    where m.From_id == selfid select m.To_id).Contains(p.Person_id) 
    select p; 
+0

不幸的是,這只是給我的消息。我追隨向我發送信息的人。 – RedBlueThing 2010-05-28 00:08:53

+0

@Cannonade我已經添加了一些更多的代碼根據您的評論,我想也許我可以改善這個使用工會,儘管這個嘗試,順便說一下,LINQPad是一個非常好的工具來嘗試這種事 – Pharabus 2010-05-28 00:55:52

+0

@Prabrabus謝謝男人......我會試試看,讓你知道我是怎麼走的。 – RedBlueThing 2010-05-28 01:39:38

0

也許嘗試聯合

select all the messages sent by user received by me 
union 
select all the messages received by user sent by me 
+0

謝謝。但我特別尋求與linq查詢語法的幫助:) – RedBlueThing 2010-05-28 01:32:38