2010-11-30 50 views
1

我有這樣的經典場景,我有一個用戶表和一個聯繫人表只包含UserId和ContactId列(所以它是一個自我多對多的relationshsip)。我想要的是一個查詢,它給了我一個具有指定用戶的常用聯繫人數的userIds列表。在普通的舊SQL我有以下查詢(用戶和用戶接觸自身被過濾出去找朋友推薦臉譜):在實體框架中查詢常見聯繫人(自我多對多關係)

SELECT COUNT(c1.ContactId) as CommonContact, c2.UserId 
from Contacts as c1 
inner join Contacts as c2 on c1.ContactId = c2.ContactId 
Where c1.UserId = @Id AND c2.UserId != @Id 
AND c2.UserId NOT IN (SELECT ContactId from Contacts Where UserId = @Id) 
Group By c2.UserId 
ORDER BY CommonContact Desc 

這個簡單的查詢工作不錯,但我無法弄清楚如何寫相同查詢在LINQ到實體,因爲在實體框架模型,我有實體有聯繫的導航性能用戶的實體,而是連接表是不是有直接....

非常感謝您的幫助......

+0

我會建議在連接表中添加一些標識字段,這將使多對多成爲一對多,多對一的關係,您將能夠很好地查詢它們。實際上,從來沒有真正的多對多關係,因爲我們總是有一些額外的屬性和連接。就像創建或更新關係和它的狀態,激活,阻止等一樣。 – 2013-07-23 20:20:16

回答

0

沒有時間,並嘗試運行它,但這樣的事情應該工作。

public class Test 
    { 
     //simulate an IQueryable 
     private readonly IQueryable<Person> _people = new List<Person>().AsQueryable(); 

     public void FindContactMatchCount(Guid personId) 
     { 
      //we'll need the list of id's of the users contacts for comparison, we don't need to resolve this yet though so 
      //we'll leave it as an IQueryable and not turn it into a collection 
      IQueryable<Guid> idsOfContacts = _people.Where(x => x.Id == personId).SelectMany(x => x.Contacts.Select(v => v.Id)); 

      //find all the people who have a contact id that matches the selected users list of contact id's 
      //then project the results, this anonymous projection has two properties, the person and the contact count 
      var usersWithMatches = _people 
       .Where(x => idsOfContacts.Contains(x.Id)) 
       .Select(z => new 
        { 
         Person = z, //this is the person record from the database, we'll need to extract display information 
         SharedContactCount = z.Contacts.Count(v => idsOfContacts.Contains(v.Id)) // 
        }).OrderBy(z => z.SharedContactCount) 
       .ToList(); 
     } 
    }