我有两个类别:LINQ内加入
List<int> ids;
List<User> users;
凡User
具有ID,姓名等
我想内部连接这两个集合,并与来自第一ID返回一个新List<int>
集合也在第二个集合中(用户标识)。
我是LINQ的新手,不知道从哪里开始。
谢谢。
我有两个类别:LINQ内加入
List<int> ids;
List<User> users;
凡User
具有ID,姓名等
我想内部连接这两个集合,并与来自第一ID返回一个新List<int>
集合也在第二个集合中(用户标识)。
我是LINQ的新手,不知道从哪里开始。
谢谢。
你并不需要用加入要做到这一点:
List<int> commonIds = ids.Intersect(users.Select(u => u.Id)).ToList();
编辑:针对在评论的问题,你可以得到用户的列表,而无需使用Join
:
var matchingUsers = users.Where(u => ids.Contains(u.Id));
但是这是非常低效的,因为Where
子句必须扫描每个用户的id列表。我想加入将处理这种情况的最好办法:
List<User> matchingUsers = users.Join(ids, u => u.Id, id => id, (user, id) => user).ToList();
在关系数据库术语,内部联接产生一个结果集,其中第一集合中的每个元素出现一次,每适配体在第二采集。如果第一个集合中的元素没有匹配的元素,它不会出现在结果集中。 Join方法由C#中的join子句调用,实现了内部联接。
本主题说明了如何进行内部的四个变体加入:
简单内加入该关联基于一个简单的按键两个数据源 元素。
一个内部联接,它基于 复合键将来自两个数据源的元素关联起来。组合键是一个由多个值组成的键,使您可以根据比一个属性更多的 关联元素。
多次连接,其中连续的连接操作被相互追加到 之间。
通过使用组连接实现的内部连接。
例 简单密钥加入实施例
下面的示例创建含有两个用户定义类型,Person和宠物的对象两个集合。查询使用C#中的join子句将Person对象与其所有者为Person的Pet对象进行匹配。 C#中的select子句定义了结果对象的外观。在这个例子中,结果对象是由所有者的名字和宠物名称组成的匿名类型。 C#
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}
/// <summary>
/// Simple inner join.
/// </summary>
public static void InnerJoinExample()
{
Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };
Person rui = new Person { FirstName = "Rui", LastName = "Raposo" };
Pet barley = new Pet { Name = "Barley", Owner = terry };
Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet bluemoon = new Pet { Name = "Blue Moon", Owner = rui };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus };
// Create two lists.
List<Person> people = new List<Person> { magnus, terry, charlotte, arlene, rui };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, bluemoon, daisy };
// Create a collection of person-pet pairs. Each element in the collection
// is an anonymous type containing both the person's name and their pet's name.
var query = from person in people
join pet in pets on person equals pet.Owner
select new { OwnerName = person.FirstName, PetName = pet.Name };
foreach (var ownerAndPet in query)
{
Console.WriteLine("\"{0}\" is owned by {1}", ownerAndPet.PetName, ownerAndPet.OwnerName);
}
}
// This code produces the following output:
//
// "Daisy" is owned by Magnus
// "Barley" is owned by Terry
// "Boots" is owned by Terry
// "Whiskers" is owned by Charlotte
// "Blue Moon" is owned by Rui
注意,Person对象,其名字是“哈夫”没有出现在结果集中,因为那里是具有Pet.Owner等于人没有宠物的对象。 示例 复合键加入示例
除了基于一个属性关联元素外,还可以使用组合键来根据多个属性比较元素。为此,请为每个集合指定键选择器函数,以返回由要比较的属性组成的匿名类型。如果标注属性,则每个键的匿名类型中必须具有相同的标签。这些属性也必须以相同的顺序出现。
以下示例使用Employee对象列表和Student对象列表来确定哪些员工也是学生。这两种类型都有一个String类型的FirstName和LastName属性。从每个列表元素创建连接键的函数返回一个由每个元素的FirstName和LastName属性组成的匿名类型。连接操作比较这些组合键是否相等,并返回每个列表中名称和姓氏匹配的对象对。 C#
class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int EmployeeID { get; set; }
}
class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int StudentID { get; set; }
}
/// <summary>
/// Performs a join operation using a composite key.
/// </summary>
public static void CompositeKeyJoinExample()
{
// Create a list of employees.
List<Employee> employees = new List<Employee> {
new Employee { FirstName = "Terry", LastName = "Adams", EmployeeID = 522459 },
new Employee { FirstName = "Charlotte", LastName = "Weiss", EmployeeID = 204467 },
new Employee { FirstName = "Magnus", LastName = "Hedland", EmployeeID = 866200 },
new Employee { FirstName = "Vernette", LastName = "Price", EmployeeID = 437139 } };
// Create a list of students.
List<Student> students = new List<Student> {
new Student { FirstName = "Vernette", LastName = "Price", StudentID = 9562 },
new Student { FirstName = "Terry", LastName = "Earls", StudentID = 9870 },
new Student { FirstName = "Terry", LastName = "Adams", StudentID = 9913 } };
// Join the two data sources based on a composite key consisting of first and last name,
// to determine which employees are also students.
IEnumerable<string> query = from employee in employees
join student in students
on new { employee.FirstName, employee.LastName }
equals new { student.FirstName, student.LastName }
select employee.FirstName + " " + employee.LastName;
Console.WriteLine("The following people are both employees and students:");
foreach (string name in query)
Console.WriteLine(name);
}
// This code produces the following output:
//
// The following people are both employees and students:
// Terry Adams
// Vernette Price
例 多重联实施例
任何数量的连接操作的可以被附加到彼此以执行多个连接。 C#中的每个连接子句都将指定的数据源与前一个连接的结果关联起来。
以下示例创建三个集合:一个Person对象列表,一个Cat对象列表以及一个Dog对象列表。
C#中的第一个连接子句根据与Cat.Owner匹配的Person对象匹配人员和猫。它返回一系列包含Person对象和Cat.Name的匿名类型。
C#中的第二个连接子句基于由Person类型的Owner属性组成的组合键,将第一个连接返回的匿名类型与提供的Dog列表中的Dog对象相关联,动物的名字。它返回包含每个匹配对的Cat.Name和Dog.Name属性的匿名类型序列。因为这是一个内部连接,所以只返回第一个数据源中第二个数据源中匹配的那些对象。 C#
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}
class Cat : Pet
{ }
class Dog : Pet
{ }
public static void MultipleJoinExample()
{
Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };
Person rui = new Person { FirstName = "Rui", LastName = "Raposo" };
Person phyllis = new Person { FirstName = "Phyllis", LastName = "Harris" };
Cat barley = new Cat { Name = "Barley", Owner = terry };
Cat boots = new Cat { Name = "Boots", Owner = terry };
Cat whiskers = new Cat { Name = "Whiskers", Owner = charlotte };
Cat bluemoon = new Cat { Name = "Blue Moon", Owner = rui };
Cat daisy = new Cat { Name = "Daisy", Owner = magnus };
Dog fourwheeldrive = new Dog { Name = "Four Wheel Drive", Owner = phyllis };
Dog duke = new Dog { Name = "Duke", Owner = magnus };
Dog denim = new Dog { Name = "Denim", Owner = terry };
Dog wiley = new Dog { Name = "Wiley", Owner = charlotte };
Dog snoopy = new Dog { Name = "Snoopy", Owner = rui };
Dog snickers = new Dog { Name = "Snickers", Owner = arlene };
// Create three lists.
List<Person> people =
new List<Person> { magnus, terry, charlotte, arlene, rui, phyllis };
List<Cat> cats =
new List<Cat> { barley, boots, whiskers, bluemoon, daisy };
List<Dog> dogs =
new List<Dog> { fourwheeldrive, duke, denim, wiley, snoopy, snickers };
// The first join matches Person and Cat.Owner from the list of people and
// cats, based on a common Person. The second join matches dogs whose names start
// with the same letter as the cats that have the same owner.
var query = from person in people
join cat in cats on person equals cat.Owner
join dog in dogs on
new { Owner = person, Letter = cat.Name.Substring(0, 1) }
equals new { dog.Owner, Letter = dog.Name.Substring(0, 1) }
select new { CatName = cat.Name, DogName = dog.Name };
foreach (var obj in query)
{
Console.WriteLine(
"The cat \"{0}\" shares a house, and the first letter of their name, with \"{1}\".",
obj.CatName, obj.DogName);
}
}
// This code produces the following output:
//
// The cat "Daisy" shares a house, and the first letter of their name, with "Duke".
// The cat "Whiskers" shares a house, and the first letter of their name, with "Wiley".
例 内部联接,通过使用分组加入实施例
以下示例说明如何实现由使用一组连接的内连接。
在查询1中,Person对象列表根据匹配Pet.Owner属性的Person,被组加入到Pet对象列表中。组联接创建一个中间组的集合,其中每个组由一个Person对象和一系列匹配的Pet对象组成。
通过在查询中添加第二个从句,该序列序列被合并(或展平)为一个更长的序列。最终序列的元素类型由select子句指定。在此示例中,该类型是由每个匹配对的Person.FirstName和Pet.Name属性组成的匿名类型。
query1的结果等同于通过使用不带into子句的join子句执行内部连接而获得的结果集。 query2变量演示了这个等价的查询。 C#
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}
/// <summary>
/// Performs an inner join by using GroupJoin().
/// </summary>
public static void InnerGroupJoinExample()
{
Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };
Pet barley = new Pet { Name = "Barley", Owner = terry };
Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet bluemoon = new Pet { Name = "Blue Moon", Owner = terry };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus };
// Create two lists.
List<Person> people = new List<Person> { magnus, terry, charlotte, arlene };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, bluemoon, daisy };
var query1 = from person in people
join pet in pets on person equals pet.Owner into gj
from subpet in gj
select new { OwnerName = person.FirstName, PetName = subpet.Name };
Console.WriteLine("Inner join using GroupJoin():");
foreach (var v in query1)
{
Console.WriteLine("{0} - {1}", v.OwnerName, v.PetName);
}
var query2 = from person in people
join pet in pets on person equals pet.Owner
select new { OwnerName = person.FirstName, PetName = pet.Name };
Console.WriteLine("\nThe equivalent operation using Join():");
foreach (var v in query2)
Console.WriteLine("{0} - {1}", v.OwnerName, v.PetName);
}
// This code produces the following output:
//
// Inner join using GroupJoin():
// Magnus - Daisy
// Terry - Barley
// Terry - Boots
// Terry - Blue Moon
// Charlotte - Whiskers
//
// The equivalent operation using Join():
// Magnus - Daisy
// Terry - Barley
// Terry - Boots
// Terry - Blue Moon
// Charlotte - Whiskers
编译代码
Visual Studio创建一个新的控制台应用程序项目。
添加对System.Core.dll的引用,如果它尚未引用。
包含System.Linq命名空间。
将示例中的代码复制并粘贴到Main方法下方的program.cs文件 中。将一行代码添加到Main方法中,以便调用 您粘贴的方法。
运行该程序。
尼斯努力在具有详细答案,尽管简洁在可能的情况下是首选。 – 2017-12-04 22:21:07
你打我吧;) – 2010-06-24 23:02:21
假设OP想要用户,而不是ID。它还可以在不加入连接的情况下完成吗? – spender 2010-06-24 23:07:18
刚刚意识到我的id实际上是long和intersect函数,默认情况下只对int集合起作用(?)。 – 2010-06-25 01:07:26