我有兩個類別: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