迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 >

使用 C# 在 LINQ 查询中按多列分组

作者:迹忆客 最近更新:2024/01/16 浏览次数:

本文简要介绍了使用 C# 进行的 LINQ 查询。此外,它还讨论了如何使用 LINQ 查询按多列对结果进行分组。

如果你已经熟悉 LINQ,则可以安全地跳过介绍部分。


LINQ 简介

LINQ 是 Language Integrated Query 的缩写,它为我们提供了一种统一的方法来访问来自不同数据源(如数据库、数组、XML 等)的数据。它本身可以集成所有查询。

当开发人员开发应用程序时,他们需要一些除编程语言之外的额外知识来从数据源获取数据。例如,如果你的数据源是数据库,则程序员需要了解 SQL。

同样,如果数据源是 XML 文档,程序员应该知道如何解析 XML。而使用 LINQ,你只需了解 LINQ 即可从所有这些数据源获取数据。

LINQ 到对象

LINQ to Objects 意味着你可以使用 LINQ 查询从内存数据结构中获取数据。此数据结构可以是用户定义的,也可以是一些 DotNet 定义的 API。

对数据结构的唯一要求是它应该返回 IEnummerable<T> 类型的集合。

让我们考虑一个 LINQ to Objects 的示例:

using System;
using System.Linq;

class MyProgram {
  static void Main() {
    string[] list = { "apple", "ball", "aeroplane", "beautiful", "ancient" };

    var starts = from w in list
                 where w.StartsWith("a") select w;
    // Print words
    foreach (var word in starts) {
      Console.WriteLine(word);
    }
  }
}

输出:

apple
aeroplane
ancient

在上面的代码片段中,我们进行了一个 LINQ 查询来访问字符串数组中的数据。这样,这个数组就可以替换成任何数据结构。

LINQ 查询的好处是无论你更改后面的数据结构,它的语法都将保持不变。查询将保持不变;这是 LINQ 提供的统一性。

LINQ 到 SQL

对于 LINQ to ADO.Net,有 3 个子组件。但是,我们将主要关注 LINQ to SQL。

LINQ to SQL 允许我们将关系数据库转换为对象。它使数据操作更加简单和快捷。

它遵循的过程是它首先连接到数据库,将 LINQ 查询转换为 SQL 查询,然后运行这些 SQL 查询。从 SQL 返回的结果被转换回 LINQ 构造的对象,然后返回给用户。

LINQ 还跟踪对象数据的变化并自动同步数据库中的这些变化。

在项目中创建 LINQ to SQL 组件时,它会自动为所有数据库表创建类。之后,你需要为连接和数据库操作编写代码。

假设我们有一个用于存储公司员工数据的表。表名称为 Emp,包含以下字段:IdNameEmail

要将其用作 LINQ 查询,请考虑以下代码片段:

using System;
using System.Linq;

namespace MyLINQExample {
   class LINQExample {
      static void Main(string[] args) {

         string connectString = System.Configuration.ConfigurationManager.            ConnectionStrings["LinqToSQLDBConnectionString"].ToString();
         LinqToSQLDataContext db = new LinqToSQLDataContext(connectString);
         Emp newEmp = new Emp();
         newEmp.name = "John";
         newEmp.email = "john@abccompany.com";
         newEmp.id = 3;
         //Add this new employee to the database
         db.Emps.InsertOnSubmit(newEmp);

         //To save changes in the database
         db.SubmitChanges();

         //Get the data of inserted employee
         Emp e = db.Emps.FirstOrDefault(e e.name.Equals("John"));

         Console.WriteLine("Emp Id = {0} , Name = {1}, Email = {2}",
                          e.id, e.name, e.email);

         Console.WriteLine("\nPress any key to continue.");
         Console.ReadKey();
      }
   }
}

在上面的代码中,我们连接到数据库,创建了一个数据上下文对象,然后让我们的查询在数据库上运行。

输出:

Emp Id = 3, Name = John, Email = john@abccompany.com

LINQ 中的连接

与简单的 SQL 查询一样,你也可以使用 LINQ 查询连接列。当你根据某些条件需要来自不同表的数据时,执行连接操作。

LINQ 提供了 join 运算符,可以轻松地连接单个或多个列。考虑我们有以下两个类:

public class Student {
  public int Stu_ID { get; set; }
  public string Stu_Name { get; set; }
  public int Class_ID { get; set; }
}

public class Grade {
  public int Grade_ID { get; set; }
  public string Grade_Name { get; set; }
}

在驱动函数中,让我们为每个类创建两个列表,如下所示:

IList<Student> students_list = new List<Student>() {
  new Student() { Stu_ID = 11, Stu_Name = "ABC", Class_ID = 1 },
  new Student() { Stu_ID = 12, Stu_Name = "DEF", Class_ID = 1 },
  new Student() { Stu_ID = 13, Stu_Name = "GHI", Class_ID = 2 },
  new Student() { Stu_ID = 14, Stu_Name = "JKL", Class_ID = 2 },
};

IList<Grade> gradeList = new List<Grade>() { new Grade() { Grade_ID = 1, Grade_Name = "Grade 1" },
                                             new Grade() { Grade_ID = 2, Grade_Name = "Grade 2" },
                                             new Grade() { Grade_ID = 3, Grade_Name = "Grade 3" } };

现在,如果我们想得到学生的名字和他们的年级,我们需要连接这两个表。这些表将分别基于 Class_IDGrade_ID 连接。

连接查询将如下所示:

var joinResult =
    from s in student_list join g in gradeList on s.Class_ID equals g.Grade_ID select new {
      StuName = s.Stu_Name, GradeName = g.Grade_Name
    };

这将产生以下输出:

ABC Grade 1
DEF Grade 1
GHI Grade 2
JKL Grade 2

使用 C# 在 LINQ 查询中按多列分组

同样,我们也可以根据某些属性对数据进行分组。这是使用 LINQ 查询中的 GroupBy 子句完成的。

GroupBy 运算符根据键值返回所提供集合中元素的子集。IGrouping<TKey, TElement> 对象代表每个组。

此外,GroupBy 方法支持不同的重载方法,因此你可以根据你的要求在方法语法中使用适当的扩展方法。

考虑以下代码:

List<Student> student_List = new List<Student>() {
  new Student() { Stu_ID = 11, Stu_Name = "ABC", Age = 18, Subject = "Arts" },
  new Student() { Stu_ID = 12, Stu_Name = "DEF", Age = 19, Subject = "Science" },
  new Student() { Stu_ID = 13, Stu_Name = "GHI", Age = 18, Subject = "Arts" },
  new Student() { Stu_ID = 14, Stu_Name = "JKL", Age = 19, Subject = "Science" },
};

假设我们要获取按年龄分组的学生列表。以下查询将为我们执行此操作:

var result = from s in student_List group s by s.Age;

foreach (var ageGroups in result) {
  Console.WriteLine("Age Group: {0}", ageGroups.Key);
  foreach (Student s in ageGroups)  // Each group has inner collection
    Console.WriteLine("Student Name: {0}", s.Stu_Name);
}

输出:

Age Group: 18
Student Name: ABC
Student Name: GHI
Age Group: 19
Student Name: DEF
Student Name: JKL

同样,我们也可以按多列分组。这是通过以下方式完成的:

var result = from s in student_List group s by new { s.Age, s.Subject };
foreach (var ageGroups in groupedResult) {
  Console.WriteLine("Group: {0}", ageGroups.Key);

  foreach (Student s in ageGroups)  // Each group has inner collection
    Console.WriteLine("Student Name: {0}", s.Stu_Name);
}

此查询将产生以下输出:

Group: {Age= 18, Subject="Arts"}
Student Name: ABC
Student Name: GHI
Group: {Age= 19, Subject="Science"}
Student Name: DEF
Student Name: JKL

上一篇:在 C# 中捕获多个异常

下一篇:没有了

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 C# 中捕获多个异常

发布时间:2024/01/20 浏览次数:135 分类:编程语言

有两种主要方法可用于捕获 C# 中的多个异常,即 Exception 类和 catch 子句中的 if 语句。使用 C# 中的 Exception 类捕获多个异常 Exception 类用于表示 C# 中的一般异常。

C# 中为无效参数或参数引发的异常类型

发布时间:2024/01/20 浏览次数:71 分类:编程语言

本教程将教你如何在 C# 中为无效参数或参数抛出不同类型的异常。异常提供有关 C# 程序中的运行时错误或预期不会发生或违反系统/应用程序约束的条件的信息。在本教程中,你将学习与无效参

C# 中的异常列表

发布时间:2024/01/20 浏览次数:128 分类:编程语言

我们将查看本文中可能引发的 C# 异常。System Exception 类是 C# 编程语言中预定义的异常类,可用于编程。选择代码中可能出现的异常并将其插入到适当的 catch 块中。

C# 中的树形数据结构

发布时间:2024/01/20 浏览次数:73 分类:编程语言

C# 中的树是本文讨论的主题。一种以树的形式组织起来的层次数据称为树数据结构。C# 中的树将是本文讨论的主题。数据结构是我们需要知道的第一件事。

C# 中的 lock 语句

发布时间:2024/01/20 浏览次数:166 分类:编程语言

C# 中 lock 语句指定的代码部分不能被多个线程同时访问。C# 中的 lock 语句 lock(obj) 语句规定,在 C# 中,下面这段代码不能被多个线程同时访问。

等待线程在 C# 中完成

发布时间:2024/01/20 浏览次数:70 分类:编程语言

等待 C# 中的线程完成的主要方法有两种:Task.WaitAll()和 Thread.Join()函数。用 C# 中的 Task.WaitAll() 方法等待线程完成 C# 中的 [Task.WaitAll() 方法)用于等待 Task 类的所有对象的完成。

C# 中的线程与任务

发布时间:2024/01/20 浏览次数:127 分类:编程语言

Thread 类创建一个实际的 OS 线程,而 Task 类创建一个在线程池中异步执行的任务。Thread 类在 C# 中创建实际的操作系统级别的线程。用 Thread 类创建的线程会占用堆栈内存等资源,上下文的 CPU 开

在 C# 中停止线程

发布时间:2024/01/20 浏览次数:138 分类:编程语言

在本文中,我将解释如何在 C# 中启动和停止线程。有时,在 C# 中使用线程时,你可能会遇到需要终止线程的情况。C# 确实为你提供了成功执行此操作的方法,本文旨在解释在 C# 中终止线程的过

C# 中的 Thread.Sleep()

发布时间:2024/01/20 浏览次数:128 分类:编程语言

在本指南中,我们将了解为什么在 C# 中使用 thread.sleep() 被认为是有害的。在本指南中,我们将了解为什么在 C# 中使用 thread.sleep() 被认为是有害的,以及为什么不应该使用这种特殊方法。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便