我有两个列表:Person类型列表和类型专业列表。两者都是多对多相关的。 另外,我有一些专业的第三个清单。 我想选择所有符合第三个清单中所有职业的人。 什么是LINQ / Lambda表达式?
由于
答案 0 :(得分:0)
答案取决于Persons
序列与Professions
序列的关联方式。
您正在讨论列表,但也涉及多对多关系,因此我假设您的列表实际上是关系数据库中的表,其中的连接表会记住哪些人员与专业相关。
如果您使用实体框架,并且正确设置了many-to-many relationship,那么您不需要第三个表格:
class Person
{
public int Id {get; set;}
... // other properties
// every Person has zero or more Professions (many-to-many)
public virtual ICollection<Profession> Professions {get; set;}
}
class Profession
{
public int Id {get; set;}
... // other properties
// every Profession has zero or more Persons (many-to-many)
public virtual ICollection<Person> Persons {get; set;}
}
class MyDbContext : DbContext
{
public DbSet<Person> Persons {get; set;}
public DbSet<Profession> Professions {get; set;}
}
就是这样!
实体框架将认识到您正在建模多对多关系,并将为其创建第三个表。您不需要第三个表,只需访问ICollections,实体框架将自动执行第三个表所需的连接。
using (var dbContext = new MyDbContext())
{
IEnumerable<Profession> professionList = ... // the third list
// Keep only the persons where have exactly all Professions from the profession list
// do this by checking the Ids of the professions in the list
IEnumerable<int> professionIds = professions
.Select(profession => profession.Id)
.OrderBy(id => id);
var personsWithProfessions = dbContext.Persons
// keep only persons that have the same Profession Ids as professionIds
// first extract the the profession Ids the person has
.Where(person => person.Professions
.Select(profession => profession.Id)
// order this in ascending order
.OrderBy(id => id)
// check if equal to professionIds:
.SequenceEqual(professionIds))
如果您没有使用Entity Framework,或者没有使用虚拟ICollection正确设置类,则您必须自己在Persons
和Professions
之间进行联接
假设您有一个加入您的人员和职业的加入表:
class Person_Profession
{
public int Id {get; set;}
public int PersonId {get; set;}
public int ProfessionId {get; set;}
}
IQueryable<Person_Profession> Person_Profession_Table = ...
首先将Person_Profession_Table中所有ProfessionIds的每个人分组。
var personsWithProfessionIds = Persons.GroupJoin(person_profession_table,
person => person.Id,
personProfession => personProfession.PersonId,
person, matchingJoiningItems => new
{
Person = person,
ProfessionIds = matchingJoiningItems
.Select(matchingJoiningItem => matchingJoiningItem.ProfessionId)
.OrderBy(id => id)
.ToList(),
})
用语言:取两个表:Persons和PersonProfessions。从每个人获取Id,从每个personProfession元素中获取PersonId,为每个人和所有匹配的personProfessions创建一个新对象:该对象包含匹配的Person,以及匹配的joinItems的所有ProfessionIds。
从这些拥有职业的人员中,只保留那些拥有所有职业人员的人员
IEnumerable<int> professionIds = professions
.Select(profession => profession.Id)
.OrderBy(id => id);
IEnumerable<Person> matchingPersons = personsWithProfessionIds
.Where(personWithProfessionId => personWithProfessioinId.ProfessionIds
.SequenceEqual(professiondIds))
.Select(personWithProfessionId => perfonWithProfessionId.Person);
答案 1 :(得分:0)
假设您的List
与其他类型的成员List
相关,
var AllPersons = new List<Person>();
var AllProfessions = new List<Profession>();
var desiredProfessions = new List<Profession>();
var findPersons = from p in AllPersons
where p.Professions.Any(pp => desiredProfessions.Contains(pp))
select p;