如何:执行自定义联接操作
联接是在不等式(非同等联接)上断言的。 联接是在多个等式或不等式上断言的。 必须在联接操作之前为右侧(内部)序列引入一个临时范围变量。
![]() |
---|
示例
class CustomJoins { #region Data class Product { public string Name { get; set; } public int CategoryID { get; set; } } class Category { public string Name { get; set; } public int ID { get; set; } } // Specify the first data source. List<Category> categories = new List<Category>() { new Category(){Name="Beverages", ID=001}, new Category(){ Name="Condiments", ID=002}, new Category(){ Name="Vegetables", ID=003}, }; // Specify the second data source. List<Product> products = new List<Product>() { new Product{Name="Tea", CategoryID=001}, new Product{Name="Mustard", CategoryID=002}, new Product{Name="Pickles", CategoryID=002}, new Product{Name="Carrots", CategoryID=003}, new Product{Name="Bok Choy", CategoryID=003}, new Product{Name="Peaches", CategoryID=005}, new Product{Name="Melons", CategoryID=005}, new Product{Name="Ice Cream", CategoryID=007}, new Product{Name="Mackerel", CategoryID=012}, }; #endregion static void Main() { CustomJoins app = new CustomJoins(); app.CrossJoin(); app.NonEquijoin(); Console.WriteLine("Press any key to exit."); Console.ReadKey(); } void CrossJoin() { var crossJoinQuery = from c in categories from p in products select new { c.ID, p.Name }; Console.WriteLine("Cross Join Query:"); foreach (var v in crossJoinQuery) { Console.WriteLine("{0,-5}{1}", v.ID, v.Name); } } void NonEquijoin() { var nonEquijoinQuery = from p in products let catIds = from c in categories select c.ID where catIds.Contains(p.CategoryID) == true select new { Product = p.Name, CategoryID = p.CategoryID }; Console.WriteLine("Non-equijoin query:"); foreach (var v in nonEquijoinQuery) { Console.WriteLine("{0,-5}{1}", v.CategoryID, v.Product); } } } /* Output: Cross Join Query: 1 Tea 1 Mustard 1 Pickles 1 Carrots 1 Bok Choy 1 Peaches 1 Melons 1 Ice Cream 1 Mackerel 2 Tea 2 Mustard 2 Pickles 2 Carrots 2 Bok Choy 2 Peaches 2 Melons 2 Ice Cream 2 Mackerel 3 Tea 3 Mustard 3 Pickles 3 Carrots 3 Bok Choy 3 Peaches 3 Melons 3 Ice Cream 3 Mackerel Non-equijoin query: 1 Tea 2 Mustard 2 Pickles 3 Carrots 3 Bok Choy Press any key to exit. */
示例
class MergeTwoCSVFiles { static void Main() { // See section Compiling the Code for information about the data files. string[] names = System.IO.File.ReadAllLines(@"../../../names.csv"); string[] scores = System.IO.File.ReadAllLines(@"../../../scores.csv"); // Merge the data sources using a named type. // You could use var instead of an explicit type for the query. IEnumerable<Student> queryNamesScores = // Split each line in the data files into an array of strings. from name in names let x = name.Split(',') from score in scores let s = score.Split(',') // Look for matching IDs from the two data files. where x[2] == s[0] // If the IDs match, build a Student object. select new Student() { FirstName = x[0], LastName = x[1], ID = Convert.ToInt32(x[2]), ExamScores = (from scoreAsText in s.Skip(1) select Convert.ToInt32(scoreAsText)). ToList() }; // Optional. Store the newly created student objects in memory // for faster access in future queries List<Student> students = queryNamesScores.ToList(); foreach (var student in students) { Console.WriteLine("The average score of {0} {1} is {2}.", student.FirstName, student.LastName, student.ExamScores.Average()); } //Keep console window open in debug mode Console.WriteLine("Press any key to exit."); Console.ReadKey(); } } class Student { public string FirstName { get; set; } public string LastName { get; set; } public int ID { get; set; } public List<int> ExamScores { get; set; } } /* Output: The average score of Omelchenko Svetlana is 82.5. The average score of O'Donnell Claire is 72.25. The average score of Mortensen Sven is 84.5. The average score of Garcia Cesar is 88.25. The average score of Garcia Debra is 67. The average score of Fakhouri Fadi is 92.25. The average score of Feng Hanying is 88. The average score of Garcia Hugo is 85.75. The average score of Tucker Lance is 81.75. The average score of Adams Terry is 85.25. The average score of Zabokritski Eugene is 83. The average score of Tucker Michael is 92. */
编译代码
创建一个面向 .NET Framework 3.5 或更高版本的 Visual Studio 控制台应用程序项目。 默认情况下,该项目具有一个对 System.Core.dll 的引用以及一条针对 System.Linq 命名空间的 using 指令。 将 Program 类替换为上述示例中的代码。 按照 How to: Join Content from Dissimilar Files (LINQ) 中的指令设置数据文件(scores.csv 和 names.csv)。 按 F5 编译并运行程序。 按任意键退出控制台窗口。