当前位置:首页>行业动态> 正文

C如何实现数据库中的两张表关联操作?

在C#中,可以使用Entity Framework Core来关联两张表。首先定义两个实体类,然后在配置类中设置它们之间的关系。

C# 中关联数据库的两张表

在 C# 应用程序中,操作数据库是一项常见的任务,一个复杂的业务逻辑需要从多个表中获取和处理数据,为了实现这一点,可以使用 ADO.NET 或更高级的 ORM(对象关系映射)工具,如 Entity Framework,本文将介绍如何在 C# 中使用 ADO.NET 来关联两张表,并展示如何查询和处理这些数据。

1. 设置数据库和表结构

假设我们有一个名为School 的数据库,其中包含两张表:StudentsCoursesStudents 表存储学生的信息,而Courses 表存储课程的信息,每张表都有一个主键,并且通过外键进行关联。

Students 表结构

列名数据类型说明
StudentIDint主键,自增
Namenvarchar学生姓名
Ageint学生年龄

Courses 表结构

列名数据类型说明
CourseIDint主键,自增
CourseNamenvarchar课程名称
StudentIDint外键,引用 Students 表

2. 使用 ADO.NET 连接数据库

需要引入必要的命名空间:

using System;
using System.Data;
using System.Data.SqlClient;

可以创建一个方法来建立数据库连接:

public static SqlConnection GetConnection()
{
    string connectionString = "Server=myServerAddress;Database=School;User Id=myUsername;Password=myPassword;";
    return new SqlConnection(connectionString);
}

3. 执行 SQL 查询以关联两张表

编写一个方法来执行 SQL 查询并获取关联的数据:

public static void GetStudentCourses()
{
    using (SqlConnection conn = GetConnection())
    {
        string query = @"SELECT Students.Name, Students.Age, Courses.CourseName 
                         FROM Students 
                         INNER JOIN Courses ON Students.StudentID = Courses.StudentID";
        
        SqlCommand cmd = new SqlCommand(query, conn);
        conn.Open();
        
        using (SqlDataReader reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                string studentName = reader["Name"].ToString();
                int age = reader.IsDBNull("Age") ? 0 : reader.GetInt32("Age");
                string courseName = reader["CourseName"].ToString();
                
                Console.WriteLine($"Student: {studentName}, Age: {age}, Course: {courseName}");
            }
        }
    }
}

在上面的代码中,使用了INNER JOIN 来关联StudentsCourses 表,并通过SqlDataReader 读取结果集。

4. 使用 Entity Framework 关联两张表

如果使用 Entity Framework,可以通过以下步骤来实现相同的功能:

安装 Entity Framework

使用 NuGet 包管理器安装 Entity Framework:

Install-Package EntityFramework

创建模型类

定义与数据库表对应的实体类:

public class Student
{
    public int StudentID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public virtual ICollection<Course> Courses { get; set; }
}
public class Course
{
    public int CourseID { get; set; }
    public string CourseName { get; set; }
    public int StudentID { get; set; }
    public virtual Student Student { get; set; }
}

配置数据库上下文

创建一个继承自DbContext 的类:

public class SchoolContext : DbContext
{
    public DbSet<Student> Students { get; set; }
    public DbSet<Course> Courses { get; set; }
    
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Server=myServerAddress;Database=School;User Id=myUsername;Password=myPassword;");
    }
}

查询数据

使用 LINQ 查询来关联两张表:

public static void GetStudentCoursesEF()
{
    using (SchoolContext context = new SchoolContext())
    {
        var studentsWithCourses = context.Students.Include(s => s.Courses).ToList();
        
        foreach (var student in studentsWithCourses)
        {
            Console.WriteLine($"Student: {student.Name}, Age: {student.Age}");
            foreach (var course in student.Courses)
            {
                Console.WriteLine($"tCourse: {course.CourseName}");
            }
        }
    }
}

FAQs

Q1: 如果我想使用左连接而不是内连接,应该如何修改 SQL 查询?

A1:你可以使用LEFT JOIN 来代替INNER JOIN

SELECT Students.Name, Students.Age, Courses.CourseName 
FROM Students 
LEFT JOIN Courses ON Students.StudentID = Courses.StudentID;

这样即使某些学生没有选修任何课程,他们也会出现在结果集中,未匹配的课程信息将为空。

Q2: 如果我希望在控制台输出中格式化输出,使其更具可读性,有什么建议吗?

A2:你可以使用字符串插值和换行符来更好地格式化输出。

Console.WriteLine($"Student: {student.Name}, Age: {student.Age}");
if (student.Courses.Any())
{
    foreach (var course in student.Courses)
    {
        Console.WriteLine($"tCourse: {course.CourseName}");
    }
}
else
{
    Console.WriteLine("tNo courses enrolled.");
}

这样可以确保每个学生的输出格式一致,并在没有选修课程时提供明确的提示。