C# 在实体框架中查询常见联系人(自多对多关系)
我有一个经典场景,其中有一个用户表和一个联系人表,其中只包含UserId和ContactId列(因此它是一个自多对多关系shsip)。我想要的是一个查询,它为我提供一个userid列表,其中包含与指定用户的常见联系人的数量。在纯旧SQL中,我有以下查询(用户和用户本身的联系人被过滤掉,以获得类似facebook的朋友建议): 这个简单的查询非常有效,但我不知道如何在LINQ中编写相同的查询到实体,因为在实体框架模型中,我有一个用户实体,该实体具有Contact导航属性,但连接表不直接存在C# 在实体框架中查询常见联系人(自多对多关系),c#,entity-framework,linq-to-entities,C#,Entity Framework,Linq To Entities,我有一个经典场景,其中有一个用户表和一个联系人表,其中只包含UserId和ContactId列(因此它是一个自多对多关系shsip)。我想要的是一个查询,它为我提供一个userid列表,其中包含与指定用户的常见联系人的数量。在纯旧SQL中,我有以下查询(用户和用户本身的联系人被过滤掉,以获得类似facebook的朋友建议): 这个简单的查询非常有效,但我不知道如何在LINQ中编写相同的查询到实体,因为在实体框架模型中,我有一个用户实体,该实体具有Contact导航属性,但连接表不直接存在 非常感
非常感谢您的帮助…没有时间尝试运行它,但类似的操作应该可以运行
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();
}
}
公共类测试
{
//模拟一个iquiryable
private readonly IQueryable_people=new List().AsQueryable();
public void FindContactMatchCount(Guid personId)
{
//我们需要用户联系人的id列表进行比较,尽管如此,我们还不需要解决这个问题
//我们将把它作为一个IQueryable,而不是把它变成一个集合
IQueryable idsOfContacts=_people.Where(x=>x.Id==personId)。选择many(x=>x.Contacts.Select(v=>v.Id));
//查找联系人id与联系人id的选定用户列表匹配的所有联系人
//然后投影结果,这个匿名投影有两个属性,person和contact count
var usersWithMatches=\u人
其中(x=>idsOfContacts.Contains(x.Id))
.选择(z=>new
{
Person=z,//这是数据库中的Person记录,我们需要提取显示信息
SharedContactCount=z.Contacts.Count(v=>idsOfContacts.Contains(v.Id))//
}).OrderBy(z=>z.SharedContactCount)
.ToList();
}
}
我建议在您的连接表中添加一些标识字段,使多对多成为一对多和多对一关系,您将能够很好地查询它们。事实上,从来没有真正的多对多关系,因为我们总是有一些额外的属性和联系。例如,关系的创建或更新时间以及状态、活动、阻止等。
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();
}
}