在实体框架中查询常见联系人(自多对多关系)

时间:2010-11-30 14:00:27

标签: c# entity-framework linq-to-entities

我有这个经典场景,我有一个User表和一个只包含UserId和ContactId列的Contact表(因此它是一个自我多对多的关系)。我想要的是一个查询,它给我一个userIds列表,其中包含指定User的常用联系人数。在普通的旧SQL中,我有以下查询(用户和用户本身的联系人被过滤掉以获取Facebook喜欢的朋友建议):

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 to Entity中编写相同的查询,因为在Entity Framework模型中我有User实体,该实体具有Contact导航属性但连接表不是直接存在的。 ...

非常感谢您的帮助......

1 个答案:

答案 0 :(得分: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();
        }
    }